总结项目中用到的@Transactional注解
由于是aop切面实现的同一级别下调用有注解的方法时不会触发事务的回滚所以一定要从a类调用b类的某个有注解的方法才能生效
1.属性说明
属性 | 是否必需 | 默认 | 描述 |
---|---|---|---|
value | 否 | 空 | 限定描述符,指定使用的事务管理器 |
transactionManager | 否 | 空 | 限定描述符,指定使用的事务管理器 |
Propagation | 否 | Propagation.REQUIRED | 事务传播行为 |
Isolation | 否 | Isolation.DEFAULT | 事务隔离级别 |
timeout | 否 | TransactionDefinition.TIMEOUT_DEFAULT(-1) | 事务超时的值默认不超时 |
readOnly | 否 | false | 设置事务是否为只读 |
rollbackFor | 否 | 空 | 触发回滚的异常;多个异常用逗号rollbackFor=Throwable.class |
rollbackForClassName | 否 | 空 | 触发回滚的异常;多个异常用逗号分割,可简化类名称如rollbackForClassName={“Exception”,”Throwable”} |
noRollbackFor | 否 | 空 | 不触发回滚的异常,多个异常用逗号分割 |
noRollbackForClassName | 否 | 空 | 不触发回滚的异常,多个异常用逗号分割,可简化类名称如noRollbackForClassName={“Exception”,”Throwable”} |
2.7种传播行为
传播行为 | 意义 |
---|---|
PROPAGATION_MANDATORY | 表示该方法必须运行在一个事务中。如果当前事务不存在,将抛出一个异常 |
PROPAGATION_NESTED | 表示如果当前已存在一个事务,则该方法应当运行在一个嵌套的事务中。被嵌套的事务可以从当前事务中单独的提交或回滚。如果当前事务不存在,那么它看起来就和PROPAGATION_REQUIRED没两样。请注意各厂商对于这种传播行为的支持是参差不齐的。请参考资源管理器的文档,确定它们是否支持嵌套事务 |
PROPAGATION_NEVER | 表示当前方法不应该运行在一个事务上下文中。如果当前存在一个事务,则会抛出一个异常 |
PROPAGATION_NOT_SUPPORTED | 表示该方法不应在事务中运行。如果一个现有的事务正在进行中,它将在该方法的运行期间被挂起。 |
PROPAGATION_REQUIRED | 表示当前方法必须运行在一个事务中。如果一个现有的事务正在进行中,该方法将运行在这个事务中。否则的话,就要开始一个新的事务 |
PROPAGATION_REQUIRES_NEW | 表示当前方法必须运行在它自己的事务里。它将启动一个新的事务。如果一个现有事务在运行的话,将在这个方法运行期间被挂起。 |
PROPAGATION_SUPPORTS | 表示当前方法不需要事务处理环境,但如果有一个事务已经在运行的话,这个方法也可以在这个事务里运行 |
3.5种隔离级别
多个事务并发运行,经常会操作同一个数据来完成任务。但是并发会导致下列问题:
- 脏读(Dirty read)——脏读发生在一个事务读取了被另一个改写但还未提交的数据时。如果这些改变在稍后被回滚,那么第一个事务读取的数据就是无效的。
- 不可重复读(Nonrepeatable read)——不可重复读发生在一个事务执行的查询两次或两次以上,但每一次查询结果都不同时。这通常是由于另外一个并发事务在两次查询之间更新了数据。
- 幻读(Phantom read)——幻读和不可重复读相似。当一个事务读取几行记录后,另一个并发事务插入一些记录,幻读就发生了。在后来的查询中,第一个事务就会发现一些原来没有的额外记录。
隔离级别 | 含义 |
---|---|
ISOLATION_DEFAULT | 使用数据库默认的隔离级别 |
ISOLATION_READ_UNCOMMITTED 读未提交 | 允许你读取还未提交的改变了的数据。可能导致脏读、幻读或不可重复读 |
ISOLATION_READ_COMMITTED 读提交 | 允许在并发事务已经提交后读取。可防止脏读、幻读或不可重复读 |
ISOLATION_REPEATABLE_READ 重复读 | 对相同字段的多次读取的结果是一致的,除非数据被事务本身改变。可防止脏读和不可重复读,但幻读仍可能发生 |
ISOLATION_SERIALIZABLE 序列化 | 完全服从ACID(原子性,一致性,隔离性,持久性)的隔离级别,确保不发生脏读、不可重复读和幻读。这在所有隔离级别中也是最慢的,因为它是典型的通过完全锁定在事务中涉及的数据表来完成的 |
ISOLATION_READ_UNCOMMITTED是最高效的隔离级别,但是事务的隔离程度也是最低的,事务对脏读、不可重复读和幻读是开放的。在另一个极端,ISOLATION_SERIALIZABLE防止任何形式的隔离问题,但效率是最低的。要知道并不是所有的事务管理器都支持表三所列的隔离级别,请参考你的事务管理器文档,来确定有哪些可使用的隔离级别。
4.只读
如果事务只针对数据库执行读操作,数据库就会针对只读特性做优化操作。
因为只读的优化措施是在事务启动时由后端数据库实施的,所以,只有将那些具有可能启动新事物的传播行为的方法的事务标记成只读才有意义(PROPAGATON_REQUIRED,PROPAGATION_REQUIRED_NEW和PROPAGATION_NEXTED)。
5.事务超时
事务可能对数据库锁定,长时间运行的事务会不必要的占用数据库资源。
6.回滚事务
rollbackFor指定了某个异常类后,方法里面抛出此类或者子类都会抛出异常。但如果默认不写就不会抛出受检查的Exception,只能回滚RuntimeException