spring系列文章
文章目录
一、使用
可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有public方法都具有该类型的事务属性。
@Transactional注解主要的属性是事务传播行为,事务隔离级别,事务超时时间,事务是否只读,事务回滚规则。
1. 事务传播行为
TransactionDefinition.PROPAGATION_REQUIRED:
如果当前没有事务,就新建一个事务,如果已经存在一个事务,则加入到这个事务中。这是最常见的选择。
TransactionDefinition.PROPAGATION_SUPPORTS:
支持当前事务,如果当前没有事务,就以非事务方式执行。
TransactionDefinition.PROPAGATION_MANDATORY:
表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常
TransactionDefinition.PROPAGATION_REQUIRED_NEW:
表示当前方法必须运行在它自己的事务中。一个新的事务将被启动。如果存在当前事务,在该方法执行期间,当前事务会被挂起。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:
表示该方法不应该运行在事务中。如果当前存在事务,就把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:
表示当前方法不应该运行在事务上下文中。如果当前正有一个事务在运行,则会抛出异常
TransactionDefinition.PROPAGATION_NESTED:
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
2. 事务隔离级别
3.回滚规则
事务回滚规则定义那些异常会导致事务回滚而那些不会。默认情况下,只有未检查异常RuntimeException和Error类的异常会导致事务回滚。
二、失效场景
1. @Tranctional应用在非public修饰的方法上
Spring AOP代理只支持public修饰的方法
2. @Tranctional注解属性propagation设置错误
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
3. @Transactional注解属性rollbackFor设置错误
rollbackFor 可以指定能够触发事务回滚的异常类型。Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务;其他异常不会触发回滚事务。如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定 rollbackFor 属性,如果未指定 rollbackFor 属性则事务不会回滚。
4. 同一个类中方法调用,导致@Tranctional失效
开发中避免不了会对同一个类里面的方法调用,比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方。
那为啥会出现这种情况?其实这还是由于使用 Spring AOP 代理造成的,因为 只有当事务方法被 当前类以外的代码 调用时,才会由Spring生成的代理对象来管理。
可以通过新增service或者在service类中注入自己