1. Spring事务的正确用法解析
作为一名Java后端开发者,我经常看到团队里的小伙伴在使用Spring事务时踩坑。Spring事务看似简单,一个@Transactional注解就能搞定,但实际使用中隐藏着不少"陷阱"。今天我就结合自己多年踩坑经验,详细剖析Spring事务的正确使用姿势。
Spring事务本质上是通过AOP代理实现的,它会在方法调用前后自动开启和提交/回滚事务。这种声明式事务管理极大简化了开发工作,但同时也带来了一些理解上的门槛。理解事务的传播机制、隔离级别、回滚规则等核心概念,是避免踩坑的关键。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 事务不回滚的五大经典场景
2.1 错误的传播特性配置
传播特性(Propagation)决定了事务如何在不同方法间传递。Spring提供了7种传播行为:
- REQUIRED(默认):如果当前存在事务,则加入该事务;如果不存在,则新建一个事务
- SUPPORTS:如果当前存在事务,则加入该事务;否则以非事务方式执行
- MANDATORY:必须在一个已有事务中执行,否则抛出异常
- REQUIRES_NEW:无论当前是否存在事务,都新建一个事务
- NOT_SUPPORTED:以非事务方式执行,如果当前存在事务则挂起
- NEVER:以非事务方式执行,如果当前存在事务则抛出异常
- NESTED:如果当前存在事务,则在嵌套事务内执行
最常见的错误是将传播特性设置为NEVER或NOT_SUPPORTED,却期望方法在事务中执行。例如:
java复制@Transactional(propagation = Propagation.NEVER)
public void updateOrder(Order order) {
// 此方法永远不会在事务中执行
orderRepository.update(order);
}
实际经验:在大多数业务场景下,使用默认的REQUIRED传播特性即可满足需求。只有在需要特殊事务边界控制时,才考虑使用其他传播特性。
2.2 异常被捕获未抛出
这是新手最容易犯的错误之一。事务回滚依赖于异常抛出,如果在方法内捕获了异常但没有重新抛出,事务管理器就无法感知异常,自然不会回滚。
java复制@Transactional
public
