1. rollbackFor没设置对,默认只有在遇到RuntimeException(运行时异常) 或者 Error 时才会回滚事务,如果出现了其他异常就不会回滚

  2. 在写代码的时候把异常catch了,但是没有throw,这样事务也无法检测到异常,不会回滚

  3. 同类之间的事务方法相互调用,被调用的方法的事务不会生效

    因为Spring的事物是基于动态代理技术实现了,而同类之间的方法调用,是普通的方法调用,不会触发spring的动态代理技术

    而事务的传播机制是在

     @Service
     public class MyService {
     ​
         @Transactional
         public void A() {
             B();
         }
         
         @Transactional
         public void B() {
             System.out.println("方法B执行了....");
         }
         
         
     }
     ​
  4. @Transactional应用在finalstatic非public、方法上时,事务也不会生效

    因为spring 的事物是基于动态代理实现了,

    非public方法的访问有限制,不能被代理,所以无法让事务生效

    final修饰的方法无法被子类重写, 所以也不能被代理,无法让事务生效

    static修饰的方法,属于类级别的方法,也不能被继承到代理对象中重写,无法代理,无法生效事务

  5. 事务传播属性的指定设计,例如以下的代码(伪代码,忽略同一个类中的方法调用影响代理的情况

    在设计了propagation = Propagation.REQUIRES_NEW的事物传播机制下,

    1中调用了2,但是2是新开了一个事务,那么1和2 ,其实就是两个相互独立的事物,互不影响

    因为两个事务之间无法保持一致性

     ​
     @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
     public void addUserAndAddress(User user,Address address) throws Exception {   //1
         userMapper.save(user);
         addAddress(address);                                                    //2
     }
     ​
     ​
     @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
     public void addAddress(Address address) {                               //2
         addressMapper.save(address);
     }
     ​
     ​
  6. 多线程环境下,也无法保存事务的一致性

    因为@Transactional是基于ThreadLocal存储上下文的,每个代理对象都会绑定到当前线程的事务上下文中,多线程情况下每个线程都有自己的上下文,事务之间无法保持一致性

  1. 如果数据库的引擎不支持事务的话,用@Transactional也没用

文章作者: 落叶知秋
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 落叶知秋
喜欢就支持一下吧