zoukankan      html  css  js  c++  java
  • spring @transactional事务问题及解决

    1. 数据库引擎选择错误

    2.@transactional标注的方法 所在的类需要被spring管理 并且方法是public修饰

    3. 自调用的时候出现的事务失效:

     1 @Service
     2 public class Service{
     3     
     4     public void m(){
     5         m1();
     6         m2();
     7 
     8     }
     9 
    10     @transactional
    11     public void m1(){
    12 
    13     
    14     }
    15     @transactional
    16     public void m2(){
    17 
    18     }
    19 }    
     1 @Service
     2 public class DmzService {
     3     @Transactional
     4     public void save(A a, B b) {
     5         saveB(b);
     6     }
     7     
     8     @Transactional(propagation = Propagation.REQUIRES_NEW)
     9     public void saveB(B b){
    10         dao.saveB(b);
    11     }
    12 }

    以上两种情况皆会导致事务失败,原因是 自调用调用的是目标类而不是代理类的方法,所以解决问题的点也在这里

    使用代理类的方法是

    1. 自己autowire注入自己

    2. 使用aopcontext

    @Service
    public class DmzService {
    
        @Transactional
        public void save(A a, B b) {
            ((DmzService) AopContext.currentProxy()).saveB(b);
        }
    
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public void saveB(B b){
            dao.saveB(b);
        }
    }

    // exposeProxy=true代表将代理类放入到线程上下文中,默认是false
    @EnableAspectJAutoProxy(exposeProxy = true)

    事务回滚问题

      1. 想回滚却提交了

      spring默认回滚是发生了error或者RunTimeException 如果想要回滚其他的异常 需要制定rollbackfor

      2. 想提交却回滚了

      

    @Service
    public class DmzService {
    
        @Autowired
        IndexService indexService;
    
        @Transactional
        public void testRollbackOnly() {
            try {
                indexService.a();
            } catch (ClassNotFoundException e) {
                System.out.println("catch");
            }
        }
    }
    
    @Service
    public class IndexService {
        @Transactional(rollbackFor = Exception.class)
        public void a() throws ClassNotFoundException{
            // ......
            throw new ClassNotFoundException();
        }
    }

    以上代码会抛出异常! 原因是 事务嵌套的情况下,当内部事务回滚会把rollbackOnly属性设置为true 所以会回滚

    解决:

      1. 如果想内部事务回滚 外部事务继续执行

        将内部事务的传播级别设置为nested或者requires_new 

        @Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)

      2. 想内部事务发生异常 外部事务回滚 整体回滚 不抛异常

    @Transactional
    public void testRollbackOnly() {
    try {
       indexService.a();
    } catch (ClassNotFoundException e) {
       // 加上这句代码
       TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
    }
    }
  • 相关阅读:
    深入V8引擎-Time核心方法之win篇(2)
    深入V8引擎-Time核心方法之win篇(1)
    深入V8引擎-Time核心方法之mac篇
    深入V8引擎-Time模块介绍
    深入V8引擎-写在前面
    深入V8引擎-编译启动
    【机器学习】极大似然估计法
    【机器学习】贝叶斯决策论
    【机器学习】贝叶斯决策 实例
    【机器学习】贝叶斯公式
  • 原文地址:https://www.cnblogs.com/isnotnull/p/14261319.html
Copyright © 2011-2022 走看看