事务管理TransactionTemplate和@Transactional注解"/>
Spring中事务管理TransactionTemplate和@Transactional注解
1. Spring支持编程式事务管理TransactionTemplate
和声明式事务管理@Transactional
两种方式
和编程式事务相比,声明式事务唯一不足地方是最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等(比如使用
AopContext.currentProxy()
)。
2. @Transactional
可通过AopContext.currentProxy()
解决在同一个类中,非事务方法A调用事务方法B,事务失效
B方法被A调用,对B方法的切入失效,但加上 AopContext.currentProxy() 创建了代理类,在代理类中调用该方法前后进行切入。对于B方法 proxy.B,执行的过程是先记录日志后调用方法体,但在A方法 proxyA中调用只能对A进行增强,A里面调用B使用的是对象.B(),而不是 $proxy.B(),所以对B的切入无效。
注:AopContext.currentProxy()使用了ThreadLocal保存了代理对象,因此
AopContext.currentProxy().B()就能解决。
public class Demo {public void methodA () {...// 获取当前代理类,保证同一个类中非事务方法调用事务方法时事务生效((Demo) AopContext.currentProxy()).methodA();...} @Transactional(rollbackFor = Exception.class)public void methodB () {...}
}
- 使用
@Transactional
声明式事务
是否在同一个类 | 调用 | 事务是否生效 |
---|---|---|
在不同类中 | 事务方法A调用非事务方法B | 事务生效 |
在不同类中 | 非事务方法A调用事务方法B | 事务生效 |
在同一个类中 | 事务方法A调用非事务方法B | 事务具有传播性,事务生效 |
在同一个类中 | 非事务方法A调用事务方法B | 事务失效 |
转载:
3. 编程式事务TransactionTemplate用法
public class Demo {@Resourceprivate TransactionTemplate transactionTemplate;public void methodA () {...// 指定事务传播性(可不设置,默认是`PROPAGATION_REQUIRED`)transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);// 指定事务隔离级别(可不设置,默认是`ISOLATION_DEFAULT`,同数据库隔离级别)transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);transactionTemplate.execute(transactionStatus -> {methodB();return Boolean.TRUE;});...} public void methodB () {...}
}
- 事务传播行为
1. TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。2. TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。3. TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。4. TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。5. TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。6. TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。7. TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
- 事务的隔离级别
1. @Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据(会出现脏读,不可重复读) 基本不使用2. @Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据(会出现不可重复读和幻读)3. @Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)4. @Transactional(isolation = Isolation.SERIALIZABLE):串行化
更多推荐
Spring中事务管理TransactionTemplate和@Transactional注解
发布评论