对于从事Java开发的小伙伴来说,spring事务它应该非常熟悉;在某些业务场景中,多张表同时写入操作。为了保证原子性,我们通常使用spring事务;在大多数情况下,spring事务可以满足需求,但同时,他也有很多坑会导致事务失败。
1.访问权限错误@Servicepublic class TestService { @Autowired private Mapper mapper; @Transactional private void test(Model model) { mapper.insert(model); }}
因为 add() 访问修饰符的方法定义为 private,因此,事务失效,spring 要求被代理的方法必须是由 public 修饰的。
因为Abstractfalbacktransactionatributesoutesoutetractionatribute方法中有一个判断,如果目标方法不是public,transactionatribute返回null,即不支持事务。
2.该方法定义为finall@Servicepublic class TestService { @Autowired private Mapper mapper; @Transactional public final void add(Model model) { mapper.insert(model); }}
由于 add 该方法定义为 final ,这样导致了 spring 的 aop 动态代理生成的代理对象不能重写该方法,导致事务失败。
3.内部调用方法@Servicepublic class TestService { @Autowired private Mapper mapper; @Transactional public void test(Model model) { mapper.insert(model); update(model); } @Transactional public void update(Model model) { // doSomeThing(); }}
我们可以看到,在事务方法add中,事务方法updatestatus直接被调用。从上面介绍的内容可以看出,updatestatus方法因为spring而具有事务能力 aop生成代理对象,但该方法直接调用this对象的方法,因此updatestatus方法不会生成事务。
4.目前的实体对象还没有被spring管理这种情况不是代码,简单来说就是没有注释,就像 service 层没有加上 @Service 注释等,未交付 spring 管理 Bean 例子,所以事务不会生成。
5.抛出异常却被自己抓获@Transactional public void test(Model model) { try { mapper.insert(model); } catch (Exception e) { log.error(e.getMessage(), e); } }
如图所示,抛出异常的方法被自己捕获,没有再抛出。事务 AOP 无法捕获异常,导致异常事务无法回滚。
6.数据库默认引擎不支持事务msql8之前的版本数据库引擎支持myslam和innerdb。我以前用过。对应的检查可以将表的数据库引擎定义为myslam,以提高查询效率。然而,我们必须记住,myslam只支持表锁,不支持事务。因此,此类表的写入操作将无效。
这是我写的第一篇博客,先简单介绍一下。 spring 几种常见的事务失败是常见的,以后我会不断更新工作中遇到的一些。 bug、技巧等;感谢您的支持!