zoukankan      html  css  js  c++  java
  • @Transactional注解的使用以及try-catch捕获异常导致@Transactional注解失效的问题

    1、事务管理是应用系统开发中必不可少的一部分。在spring boot 中,使用事务非常简单,只要直接在方法上面加入@Transactional 就可以实现。

    2、SpringBoot项目会自动配置一个 DataSourceTransactionManager,所以我们只需在方法(或者类)加上 @Transactional 注解,就自动纳入 Spring 的事务管理了。

    如下在方法加上 @Transactional 注解:

    @Transactional
    public void insertUser() {
        User user = new User("张三");
        userMapper.insertOneUser(user);          //向数据库插入一条记录
        throw new RuntimeException("发生异常");   //手动模拟抛出异常
    }
    

    抛出异常之后,事务会自动回滚,数据不会插入到数据库。

    • 当Transaction内发生unchecked exception的时候,会自动rollback,但是当Transaction内发生checked exception时,是不会自动rollback的。
    • 如果使用try-catch捕获异常,则该事务不会回滚。

    3、默认spring事务只在发生未被捕获的 RuntimeException 时才回滚。

    spring aop异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获RuntimeException的异常,但可以通过配置来捕获特定的异常并回滚。
    换句话说在service的方法中不使用try catch或者在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被aop捕获进而回滚。

    解决方案:

    • 方案1.例如service层处理事务,那么service中的方法中不做异常捕获,或者在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理。

    • 方案2.在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常。

    例如

    catch (Exception e)
    {
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚
        result.put("status", 0);
        result.put("msg",msg);
        return result;
    }
    

    4、总结:如果是try-catch捕获异常引起的@Transactional注解失效,只要手动抛出RuntimeException()或者在catch中使用TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句就可以解决。

    5、参考博客:

  • 相关阅读:
    排序算法——希尔排序
    排序算法——直接插入排序
    排序算法——快速排序
    排序算法——冒泡排序
    一个echarts柱状图hover改变颜色的例子
    vue使用sockjs-client+stompjs进行websocket连接的方法
    vue学习日记:使用vue-cli搭建项目支持ie10和ie11的一些尝试
    vue学习日记:axios拦截器的配置
    vue学习日记:iview组件库的使用
    vue学习日记:vue发送请求
  • 原文地址:https://www.cnblogs.com/myblog001/p/13191729.html
Copyright © 2011-2022 走看看