Spring 自调用事务失效分析及解决办法

前言

博主在写公司需求的时候,有一个操作涉及到多次对数据库数据的修改。当时就想着要加 @Transactional注解来声名事务。并且由于一个方法中有太多行了,于是就想着修改数据库的操作单独提取出来抽象成一个方法。但这个时候,IDEA 提示我自调用导致事务不会生效。

所谓Spring子调用 ,就是在Service方法内,调用另一个加了@Transactional注解的方法,那么这个时候注解失效,要如何解决呢?

1. 事务介绍

在开发中涉及到同事操作多个表的时候,要保证两个操作要么一起成功,要么一起失败。此时就需要用到:事务。

现在一般使用的都是基于 @Transactional 注解的声明式事务

而在使用事务的过程中,需要注意以下几点:

  1. 事务只能应用到 pulic****修饰的方法上才会生效。
  2. 事务需要从外部调用(涉及到事务的实现原理:基于动态代理实现的)。 Spring****自调用会失效。
  3. 建议 @Transactional****注解添加到 Service 实现类上。

这些要求或者注意事项官方文档可是明确说明的!

应仅将 @Transactional 注解应用于具有公开可见性的方法。如果对受 protected, private 或 package-visible 修饰的方法使用,则不会引发任何错误,但是被注解的方法不会显示已配置的事务设置。

至于建议加在实现类上,这个只是建议,不过如果加在接口类或接口方法上时,只有配置基于接口的代理才会生效。所以这块还是老老实实的加在实现类或实现类方法上吧。

2. 使用场景

在实际开发中,我们经常会遇到这种情况!

本来这块的代码逻辑就很复杂,导致我们写的方法可能又臭又长,里面有各种逻辑操作。在需要同时操作多个表进行更新的时候,就想着单独抽成一个方法让事务包裹的范围最小,仅仅在同时更新的时候加上事务。但此时会发现事务无法生效。如前言所示。那我们如何解决呢?请看下面的三种方法

3. 解决方案

3.1. 外部调用

自调用不允许,那改成外部调用即可。

再声明一个 Service,把更新表的逻辑放过去。

3.2. 使用编程式事务(不推荐)

使用编程式事务,既然使用声明式事务有这么多的显示,那可以换一种编程式事务!

此方法编写较为复杂,不推荐

此时,哪怕方法是private修饰的,事务都可以生效。

3.3. 调用外部方法,外部方法调用内部方法

那如果我们那又想用注解,又想自调用怎么办呢?

咱们可以参考编程式事务的方式,不就是不让自调用么,我调外部方法,然后外部方法再给我调回来不就可以了。

复制代码
@Component
public class TransactionalComponent {

    public interface Cell {
        void run() throws Exception;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void required(Cell cell) throws Exception {
        cell.run();
    }
}

这样的话不就可以通过 TransactionalComponent 调用了么,并且还可以使用 lambda 表达式。

4. 总结

本文注解介绍了事务,以及事务失效的解决办法。综上,博主更推荐也更喜欢用第一种方式来解决自调用事务失效的问题。

相关推荐
S***267532 分钟前
基于SpringBoot和Leaflet的行政区划地图掩膜效果实战
java·spring boot·后端
马剑威(威哥爱编程)1 小时前
鸿蒙6开发视频播放器的屏幕方向适配问题
java·音视频·harmonyos
JIngJaneIL1 小时前
社区互助|社区交易|基于springboot+vue的社区互助交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·社区互助
晚风吹人醒.1 小时前
缓存中间件Redis安装及功能演示、企业案例
linux·数据库·redis·ubuntu·缓存·中间件
Y***98511 小时前
DVWA靶场通关——SQL Injection篇
数据库·sql
Yawesh_best1 小时前
告别系统壁垒!WSL+cpolar 让跨平台开发效率翻倍
运维·服务器·数据库·笔记·web安全
V***u4531 小时前
MS SQL Server partition by 函数实战二 编排考场人员
java·服务器·开发语言
蒋士峰DBA修行之路1 小时前
实验二十八 SQL PATCH调优
数据库·sql·gaussdb
这是程序猿2 小时前
基于java的ssm框架旅游在线平台
java·开发语言·spring boot·spring·旅游·旅游在线平台
I***t7162 小时前
一条sql 在MySQL中是如何执行的
数据库·sql·mysql