人月聊IT

分布式事务

  • 分段式提交,基于XA

    提交动作分为预提交和正式提交;预提交全成功,commit;commit失败预提交全部回滚。

    • 缺点:宕机,死锁。
  • TCC
  • BASE 最终一致性;配合消息中间件(解耦、重试)。

2022年4月5日

Spring事务失效的几个场景

Spring声明式事务是基于AOP动态代理的,最终是调用数据库的connection.commit或者connection.rollBack。

  1. 事务方法访问修饰符非public,导致事务失效。
    1. 原因:非public修饰的方法,Spring不会进行事务的管理。
    2. 解决:1、改为public;2、开启AspectJ代理模式。
    3. 其他:static、final修饰的方法也无法通过动态代理,事务不会生效
  2. 不是注解支持的异常,事务失效。
    1. 原因:Spring事务默认只支持未检查异常(unchecked),不支持已检查的异常(checked)。
    2. 解决:1、指定事务出发异常;2、抛出未检查异常。
  3. 数据库本身不支持事务(如mysql的MyIsm引擎)
  4. @Teansaction注解所在的类没有被Spring管理
    1. 原因:不会被加载为Bean,不会代理。
  5. try catch吞掉异常
    1. 原因:吞掉后没有手动抛出异常,未触发事务。
  6. 类调用本身方法,事务失效
    1. 原因:如this.instertMapper(xx);自己调用自己不会被代理。(事务注解的实现基于AOP,AOP实现原理是动态代理,自己调用自己不存在代理对象的调用,这样就不会产生AOP去为事务注解配置参数生效事务。)
  7. 数据源没有配置事务管理器。(较少)
  8. 传播类型不支持事务(@Transaction(propagation=Propagation.NOT_SUPPORTED)// 以非事务的方式运行)
  9. 多线程调用导致事务失效
    1. 原因:始于基于数据库连接,多线程不是一个数据库连接。