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 事务失效

转载:https://www.jianshu.com/p/2ab568e7aaf7

3. 编程式事务TransactionTemplate用法

public class Demo {

    @Resource
    private 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):串行化

猜你喜欢

转载自blog.csdn.net/qq_40406380/article/details/124380675