从@Transactional失效场景到传播行为原理

大家有没有见过这种场景:就是再写后端接口的时候,你的实现层上面写了事务回滚的注解,但是前端调用接口传参插入或修改时即使报错了,但是这些垃圾数据还是添加或者修改了数据库中的数据呢!

难道注解失效了吗?但一旦遇到这种问题就容易懵圈。 那么这次就好好的分析分析从常见的@Transactional失效场景到传播行为的原理的理解

一、@Transactional为什么会失效?

先来看一个实际开发中经常遇到的场景:你在一个类的方法上加了@Transactional注解,满心期待着出现异常时数据会自动回滚,结果却发现事务根本没生效!这种情况通常有以下几种原因:

  1. 注解放在了私有方法上 :Spring事务是通过代理实现的,私有方法无法被代理,所以放在私有方法上的@Transactional注解根本不会生效。记住,它只能放在public方法上。

  2. 自调用问题:这是最容易出现问题的。当一个类中的方法A(没有事务注解)调用同一个类中的方法B(有@Transactional注解)时,事务是不会生效的。因为Spring的事务管理是通过代理对象实现的,自调用绕过了代理机制。

java 复制代码
@Service
public class UserService {
    
    public void createUser(User user) {
        // 这个方法调用了本类的其他方法
        validateUser(user); // 这里的事务会生效吗?
        saveUser(user); // 不会!
    }
    
    @Transactional
    public void saveUser(User user) {
        userDao.save(user);
    }
}
  1. 异常类型不正确:默认情况下,Spring只会在抛出运行时异常(RuntimeException)或Error时回滚事务。如果你抛出了检查异常(比如Exception),事务是不会回滚的。

二、Spring事务传播行为的原理

事务传播行为定义了一个事务方法被另一个事务方法调用时,事务应该如何传播。Spring提供了7种传播行为,但最常用的是以下三种:

  1. REQUIRED(默认):如果当前存在事务,就加入该事务;如果当前没有事务,就新建一个事务。这是最常用的传播行为。

这就好像朋友聚餐:如果有人已经订了包间(已有事务),你就直接加入;如果没人组织,你就自己订一个包间(新建事务)。

  1. REQUIRES_NEW:无论当前是否存在事务,都新建一个事务。如果当前有事务,就把当前事务挂起。

这好比公司开会时,老板突然要开个紧急小会:不管原来在开什么会,先暂停,开完小会再继续原来的会议。

  1. NESTED:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则新建一个事务。

这有点像写文章时的"撤销"功能:你可以在一篇文章中做一些修改,如果不满意可以回滚到保存点,而不影响整篇文章。

三、工作中如何选择?

  • 大多数情况下,我们选择使用默认的REQUIRED就足够了
  • 当你需要确保某些操作无论如何都要提交,不受主事务回滚影响时,使用REQUIRES_NEW
  • 当你希望部分操作可以独立回滚而不影响主事务时,使用NESTED

四、小小建议

  1. 明确指定回滚异常:虽然Spring有默认行为,但最好明确指定回滚的异常类型,避免意外情况。
java 复制代码
@Transactional(rollbackFor = Exception.class)
  1. 只在需要的方法上使用事务:不要滥用@Transactional,因为事务是有性能开销的。

  2. 设置合适的事务超时时间:避免长时间占用数据库连接。

java 复制代码
@Transactional(timeout = 30)
  1. 读取操作设置为只读:如果你的方法只读取数据,设置readOnly = true可以提高性能。
java 复制代码
@Transactional(readOnly = true)

OK!本次的分享就到此结束,看看自己的项目中的@Transactional是否正确吧!

相关推荐
就叫_这个吧5 小时前
Java递归方法实现面包屑导航
java·开发语言
fīɡЙtīиɡ ℡5 小时前
AI 应用系统设计
java·开发语言·人工智能
城管不管5 小时前
重生——第十一次面试之挖财一面2026.8.19已OC
java·服务器·jvm·数据库·spring·面试·职场和发展
码匠许师傅5 小时前
【C++ 面试真题】26. 聊聊 C++ 的智能指针
java·c++·面试
AI绘画哇哒哒5 小时前
【建议收藏!】35岁后端血泪忠告,这3类人别硬转Agent(过来人亲述)
java·人工智能·后端·ai·程序员·大模型·agent
最强小杰6 小时前
gpt-5.6-sol 频繁报 503 怎么办?区分容量熔断和限速 429 的排查方法 + 可复用 retry wrapper
java·人工智能·gpt·ai
唐青枫6 小时前
一个值多种形态:Zig union、Tagged Union 与内存布局实战
后端
卷无止境7 小时前
Windows 上丝滑开发 Python,并稳定构建 Docker 镜像
后端·python·docker
Nturmoils7 小时前
备份完不算完,先还原到临时库验一遍
后端
Csvn7 小时前
📊 SQL 入门 Day 22:视图与物化视图
后端·sql