Spring事务原理之初始化

事务管理抽象

Alt text

事务管理实现方式

编程式事务管理

编程式事务管理基本上很少用到,但是在某些场合下还是一柄利器,可以解决比较棘手的问题。使用编程式事务管理,必须要用到TransactionTemplateAlt text TransactionTemplate主要有两个方法

使用XML配置声明式事务管理

使用注解配置声明式事务管理

@Transactional注解。前提是Spring的配置文件中标注

//transaction-manager可以不用指定,默认是transactionManager
<tx:annotation-driven transaction-manager="transactionManager" />

值得注意的是,@Transactional可以用在接口定义、接口方法、类定义、类的public方法上。方法上的注解会覆盖类上的注解。

异常回滚规则

Spring事务初始化

首先,要了解Spring事务初始化,必须要先了解AOP。其次,了解AOP还必须要先了解IoC容器中Bean的生命周期,这样才能融会贯通,柳暗花明。

IoC容器中Bean的生命周期

Alt text

AOP

AOP实现

Alt text

AOP术语

Spring如何加载事务增强

以注解配置声明式事务管理为例子

关键点

解析tx:annotation-driven

Alt text

Spring生成代理类

Alt text

SpringAOP(事务)注意事项

JDK动态代理

在JDK动态代理中通过接口来实现方法拦截,所以必须要保证被拦截的目标方法在接口中有定义,否则将无法拦截

CGLIB动态代理

在CGLIB动态代理中通过动态生成子类来实现方法拦截,所以必须要确保被拦截的目标方法可被子类访问,也就是目标方法必须定义为非final,非private方法

类内部调用自身方法无法进行代理

以CGLIB动态代理为例子

public class Source{
  @Transactional
  public void add(){
    //其他代码
    try {
      minus();
    }catch (Exception e) {
    }
  }
  @Transactional
  public void minus(){
  }
}
public class SourceProxy extends Source{
  public void add(){
    //增加事务管理
    super.add();
  }

  public void minus(){
    //增加事务管理
    super.minus();
  }
}
public class Test{
  @Autowired
  Source source;

  public void test() {
    source.add();
  }
}

在执行Test#test()方法调用Source#add()时,如果Source#minus()发生异常,minus方法并不会进行回滚,因为Source#minus()并没有加入事务管理器。这是因为在实际执行过程中调用的是代理类SourceProxy#add(),进一步调用的是Source#add(),只有当Source#add()发生异常时才会进行事务处理(Source#minus()产生的异常被捕获了)

public class Source{
  private Source sourceProxy;
  @Transactional
  public void add(){
    //其他代码
    try {
      sourceProxy.minus();
    }finally{

    }
  }
  @Transactional
  public void minus(){
  }
}
文章目录