概述
Spring 事务管理是确保数据库操作原子性、一致性、隔离性和持久性(ACID)的核心机制。通过声明式或编程式方式管理事务,支持多种事务传播行为和隔离级别。相较于编程式事务,声明式事务通过 @Transactional 注解实现,无需手动编写事务代码。
@Transactional 注解
该注解提供声明式事务管理,简化了应用程序中管理数据库事务的流程。开发者只需在方法或类上添加此注解,Spring 框架就会自动处理事务的开启、提交和回滚。
使用级别:
- 类级别: 为类中所有 public 方法添加注解。
- 方法级别: 默认仅对 public 方法生效。
@RequestMapping("/test")
@RestController
@Slf4j
public class TestController {
private final UserService userService;
@Autowired
public TestController(UserService userService) {
this.userService = userService;
}
@Transactional
@RequestMapping("/test1")
public String test1(String userName, String password) {
UserInfo userInfo = new UserInfo();
userInfo.setUserName(userName);
userInfo.setPassword(password);
Integer result = userService.register(userInfo);
if (result == 1) {
log.info("test1 注册成功,userName:{},password:{}", userName, password);
}
return "注册成功";
}
}
回滚策略
默认情况下,抛出非受查异常(RuntimeException)或错误(Error)时触发回滚。若需指定其他异常类型,可使用 rollbackFor 属性。
指定回滚类型示例:
@Transactional(rollbackFor = Exception.class)
@RequestMapping("/test4")
public String test4(String userName, String password) throws IOException {
// ... 业务逻辑 ...
throw new IOException();
}
当抛出受检异常(如 IOException)而未配置 rollbackFor 时,事务不会回滚;配置后则正常回滚。反之,抛出 RuntimeException 时无论是否配置均会回滚。
隔离级别
用于指定事务的隔离级别,可选值包括:
Isolation.DEFAULT:使用底层数据库默认的隔离级别。Isolation.READ_UNCOMMITTED:读未提交。Isolation.READ_COMMITTED:读已提交。Isolation.REPEATABLE_READ:可重复读。Isolation.SERIALIZABLE:串行化。
每种隔离级别的具体效果取决于底层数据库的实现,通常建议遵循数据库默认设置,除非有明确的并发控制需求。
传播行为
定义当前事务方法被另一个事务方法调用时,事务应如何传播。Spring 提供了 7 种传播行为,均基于 Propagation 枚举类实现。
-
Propagation.REQUIRED 默认传播行为。如果当前存在事务,则加入该事务;如果不存在事务,则新建一个事务。
-
Propagation.SUPPORTS 如果当前存在事务,则加入该事务;如果不存在事务,则以非事务方式执行。
-
Propagation.MANDATORY 强制要求当前存在事务并加入,否则抛出异常。
-
Propagation.REQUIRES_NEW 无论当前是否存在事务,都新建一个事务。新事务与当前事务独立,互不干扰。常用于需要记录日志或审计的场景,确保其不受外部事务影响。
-
Propagation.NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,则挂起该事务。
-
Propagation.NEVER 强制要求当前不能存在事务,否则抛出异常。
-
Propagation.NESTED 如果当前存在事务,则在嵌套事务中执行;如果不存在事务,则行为与
Propagation.REQUIRED相同。嵌套事务的回滚不影响外部事务,但外部事务回滚会导致嵌套事务回滚。适用于需要部分回滚的场景。
在实际开发中,理解这些传播行为的差异对于处理复杂的业务逻辑至关重要,特别是涉及跨服务调用或多层方法调用的场景。


