zoukankan      html  css  js  c++  java
  • spring事务控制采坑日记

    用spring做事务控制有一段时间了,习惯了在方法上加@Transactional注解,今天发现一个问题,在这里记录一下,下面是一段伪代码来描述业务场景

    public class OrderServiceImpl implements OrderService{ 
      
        public BaseResponse confirmOrder(){
    
            //do something  
    
            //新增订单数据,需要做事务控制
            addOrder (); 
    
            //do other 
        }
    
        @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
        public int addOrder(Order order){
            ...
        }
    
    }

    由于需要做事务控制的代码只有一段,故将此部分代码抽出来添加事务控制,但是由于调用addOrder方法默认是this.addOrder调用,并不是通过代理对象调用的,故spring是无法做事务控制的。

    改进方式1

        添加一个dao层,用于专门做事务控制,所有需要事务控制的方法在此层实现

    改进方式2

        将直接调用 addOrder() 改成 ((OrderService) AopContext.currentProxy()).addOrder() ,其中OrderService是当前类实现的接口。

        这样就是通过代理对象来执行,不会影响事务。因为是内部的自我调用,所以需要在spring配置中添加

    <aop:aspectj-autoproxy expose-proxy="true"/>

        否则会抛出如下错误

    java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available

    实际开发中,service可能是对外暴露的协议,如果不想将此方法暴露出去,可以再实现一个新接口,在新接口中添加此方法,java虽然不允许多继承,但是可以实现多个接口。

  • 相关阅读:
    python 操作 mysql 数据库 datetime 属性字段为 0000-00-00 00:00:00 的问题
    git 学习笔记
    SB Admin 2 学习笔记1
    docker容器与容器云读书笔记1
    urlencode遇到中文编码问题
    flask_sqlalchemy 乱码问题
    centos6u3 安装 celery 总结
    flask_sqlalchemy 命名遇到的一个小坑
    使用 bash 创建定时任务
    tornado 异步调用系统命令和非阻塞线程池
  • 原文地址:https://www.cnblogs.com/1ning/p/9208401.html
Copyright © 2011-2022 走看看