zoukankan      html  css  js  c++  java
  • springboot事务中的一些坑

    springboot开启声明式事务方式

    • 在Application启动类中加入注解@EnableTransactionManagement(mode = AdviceMode.PROXY)
    • 在需要加入事务的方法上加入注解@Transactional
    • @Transactional(rollbackFor = RollbackException.class) 抛出指定异常时回滚
        /**
         * <p>
         *      (rollbackFor = RollbackException.class) 抛出自定义异常时,回滚事务。
         * </p>
         * @throws RollbackException
         */
        @Override
        @Transactional(rollbackFor = RollbackException.class)
        public void insertThenRollback() throws RollbackException {
            jdbcTemplate.execute("INSERT INTO Student (NAME) VALUES ('Tom')");
            throw new RollbackException();
        }
    

    常见问题

    例如有这个实现类StudentServiceImpl:

    @Component
    public class StudentServiceImpl implements StudentService {
    
        /**
         * <p>
         *      (rollbackFor = RollbackException.class) 抛出自定义异常时,回滚事务。
         * </p>
         * @throws RollbackException
         */
        @Override
        @Transactional(rollbackFor = RollbackException.class)
        public void insertThenRollback() throws RollbackException {
            jdbcTemplate.execute("INSERT INTO Student (NAME) VALUES ('BBB')");
            throw new RollbackException();
        }
        
            /**
         * <p>
         *      spring的事务是通过aop进行代理增强的。
         *      这里是在类的内部直接执行方法调用,并没有调用代理类来进行方法调用,所以这里事务不会回滚。
         * </p>
         *
         * @throws RollbackException
         */
        @Override
        public void invokeInsertThenRollback1() throws RollbackException {
            insertThenRollback();
        }
        
    }
    

    上面的insertThenRollback()回回滚事务,invokeInsertThenRollback1()调用了insertThenRollback()方法但是不会回滚事务,这是为什么呢?
    这是因为spring的事务是通过aop进行代理增强的,但这里是在类的内部直接执行方法调用,并没有调用代理类来进行方法调用,所以这里事务不会回滚。

    解决办法

    • 第一种方法:通过AopContext.currentProxy()获取当前类的代理对象。
        /**
         *
         * 通过AopContext.currentProxy()获取当前类的代理对象
         *
         * @throws RollbackException
         */
        @Override
        public void invokeInsertThenRollback2() throws RollbackException {
            ((StudentService) (AopContext.currentProxy())).insertThenRollback();
        }
    
    • 第二种方法:把自己的实例注入进来,让spring为我们创建代理。
        //把自己的实例注入进来
        @Autowired
        private StudentService studentService;
        
        
        /**
         * 把自己的实例注入进来
         * @throws RollbackException
         */
        @Override
        public void invokeInsertThenRollback3() throws RollbackException {
            studentService.insertThenRollback();
        }
    
  • 相关阅读:
    可自主二次开发的微信云控客服crm系统软件(带源码)
    个人微信号二次开发sdk协议,微信个人号开发API接口
    最新的微信SCRM客服系统
    微信个人号客服系统淘宝客发单机器人sdk服务端接口列表
    sdk定制开发微信群控云控客服系统教程
    web版微信自动发消息(实现微信个人号机器人)
    Adobe Audition 基本使用
    MPEG-7 视觉描述符
    图像检索:几种基于纹理特征的图像检索算法
    div+css基础教程
  • 原文地址:https://www.cnblogs.com/monkjavaer/p/11461946.html
Copyright © 2011-2022 走看看