• 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();
    }
    }
  • 相关阅读:
    OpenSSL: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
    Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
    for循环用了那么多次,但你真的了解它么?
    使用git克隆github上的项目失败,报错error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054
    idea修改svn地址
    Eureka服务注册中心错误:com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
    Tensorflow学习资源
    编程工具使用技巧
    博客链接
    python学习笔记
  • 原文地址:https://www.cnblogs.com/isnotnull/p/14261319.html
Copyright © 2020-2023  润新知