Spring事务(一)

Spring事务的实现原理:

  1. Spring事务底层是基于数据库事务和AOP机制的
  2. ⾸先对于使⽤了@Transactional注解的Bean,Spring会创建⼀个代理对象作为Bean
  3. 当调⽤代理对象的⽅法时,会先判断该⽅法上是否加了@Transactional注解
  4. 如果加了,那么则利⽤事务管理器创建⼀个数据库连接
  5. 并且修改数据库连接的autocommit属性为false,禁⽌此连接的⾃动提交。
  6. 然后执⾏当前⽅法,⽅法中会执⾏sql
  7. 执⾏完当前⽅法后,如果没有出现异常就直接提交事务
  8. 如果出现了异常,并且这个异常是需要回滚的就会回滚事务,否则仍然提交事务

Spring的事务可分为编程式事务和声明式事务
声明式事务存在的问题:

  1. 最小粒度也要作用在方法上,那么如果这个方法里有一些如RPC远程调用、消息发送、缓存更新、文件写入等操作。本地事务回滚了,这些操作也无法回滚。如果是编程式事务的话,业务代码中就会清清楚楚看到什么地方开启事务,什么地方提交,什么时候回滚。
  2. 相对而言声明式事务更容易失效
    如以下几种场景就可能导致声明式事务失效:
  • @Transactional 应用在非 public 修饰的方法上
    spring要求被代理方法必须是public的

  • 方法用final修饰
    spring的事务是根据aop来实现的切面增强,而spring的aop默认用的是cglib动态代理。cglib是基于父子类来进行动态代理的,会动态的帮我们生成代理类,而这个代理类又是继承于被代理类的。而如果父类的方法不是public的,子类就无法重写,也就不能进行增强了。

  • 同一个类中方法调用,导致@Transactional失效
    发⽣⾃调⽤,类⾥⾯使⽤this调⽤本类的⽅法(this通常省略),此时这个this对象不是代理类,⽽是对象本身

  • 未被spring容器管理
    就是这个bean没有被容器管理

  • @Transactional 注解属性 propagation 设置错误
    目前只有这三种传播特性才会创建新事务:NESTED,REQUIRES_NEW,REQUIRED。

  • @Transactional 注解属性 rollbackFor 设置错误
    rollbackFor是导致事务回滚的异常类数组,所有在这个数组当中的异常被catch了就会回滚,反之则不会回滚。所以如果手动抛了其他的异常,事务也不会回滚。

  • 数据库引擎不支持事务

你可能感兴趣的:(Spring事务(一))