编程语言
首页 > 编程语言> > 99%的Java程序员都不知道的Spring中的@Transactional注解的坑

99%的Java程序员都不知道的Spring中的@Transactional注解的坑

作者:互联网

  在我们开发中很多时候都要用到事务,例如转账、充值等等的操作,这些我就不多BB了,于是很多人就选择最简单的方式@Transactional注解,但是你真的测试过事务异常的时候会回滚吗?等生产环境遇到了在来查找原因那就晚了,下面就说一下该注解的一下坑吧。

Transactional常见的几种失效原因

  那什么是checked异常,什么是unchecked异常?我们把派生于Error或者RuntimeException的异常称为unchecked异常,所有其他的异常成为checked异常。什么又是RuntimeException呢,用《Effective Java》上的一句话来说吧。

  Use checked exceptions for recoverable conditions and runtime exceptions for programming errors (Item 58 in 2nd edition)

  从这句话中我们可以简单引申一下,也就是说,如果出现了RuntimeException,就一定是程序员自身的问题。比如说,数组下标越界和访问空指针异常等等,只要你稍加留心这些异常都是在编码阶段可以避免的异常。

  针对最后一种情况,我们简单模拟一下吧,前期的准备工作这里就跳过了,直接开始我们今天的测试。测试之前数据库中的emp表只有一条数据信息。

51.png


unchecked异常事务回滚验证

  现在我们先模拟正常情况(RuntimeException, 我们使用最简单的数组越界异常。)   废话不多说,直接上代码:

    @Test     @Transactional     public void test(){         Emp emp1 = new Emp();         emp1.setEmpname("测试二");         emp1.setEmail("test02@qq.com");         empService.×××ertEmp(emp1);         /**          * 模拟RuntimeException异常回滚          * */         int[]  arr = {0};         System.out.println(arr[1]);//越界         Emp emp2 = new Emp();         emp2.setEmpname("测试三");         emp2.setEmail("test03@qq.com");         empService.×××ertEmp(emp1);     }

  运行之后效果截图:

51.png

程序运行之后,我们看下数据库的数据情况:

51.png  

代码运行之后,由于有RuntimeException异常抛出,所以事务回滚了,这两条数据都没保存成功。 

checked异常事务回滚验证

  接下来模拟checked异常事务是否回滚问题,我们强制抛出一个FileNotFoundException异常。 ??   同样的,这里粘贴一下测试用的代码:

    @Test     @Transactional     public void test() throws Exception{         Emp emp1 = new Emp();         emp1.setEmpname("测试四");         emp1.setEmail("test04@qq.com");         empService.×××ertEmp(emp1);                  /**          * 文件一定不存在          * */         FileInputStream file = new FileInputStream("C:\\Users\\pokemon\\Documents\\abc.txt");                  Emp emp2 = new Emp();         emp2.setEmpname("测试五");         emp2.setEmail("test05@qq.com");         empService.×××ertEmp(emp1);     }

  报错情况:

51.png

程序运行之后,我们看下数据库的数据情况:

51.png

从上面的截图可以看出,事务并没有回滚,empname是“测试四”的这条数据被写入数据库了。

  等等,这种情况我们无法预料,那应该怎么办?总不能坐以待毙吧。


标签:回滚,Java,Spring,Transactional,事务,Emp,emp1,异常
来源: https://blog.51cto.com/14378044/2409218