1.概述
Spring 事务管理是 Spring 框架中用于确保数据库操作原子性、一致性、隔离性和持久性 (ACID) 的核心机制。它通过声明式或编程式方式管理事务,支持多种事务传播行为和隔离级别。相较于编程式事务,声明式事务通过
@Transactional注解实现事务管理,无需手动编写事务代码。
2.@Transactional
作用:提供声明式事务管理。它简化了在应用程序中管理数据库事务的流程。开发者只需在方法或类上添加此注解,Spring 框架就会自动处理事务的开启、提交和回滚,无需手动编写事务管理代码 (如 begin、commit、rollback)。 **级别:**类 + 方法。作为类注解:为类中所有 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 "注册成功";
}
}
执行 PostMan 请求后,若业务逻辑正常,MySQL 事务提交,后端日志记录成功信息。
2.1 rollbackfor
**作用:**指定哪些异常触发回滚,默认情况下在抛出 非受查异常 (RuntimeException)/错误 (Error) 时触发回滚。
指定回滚类型
@RequestMapping("/test")
@RestController
@Slf4j
public class TestController {
private final UserService userService;
@Autowired
public TestController(UserService userService) {
this.userService = userService;
}
@Transactional(rollbackFor = Exception.class)
@RequestMapping("/test4")
public String test4(String userName, String password) throws IOException {
UserInfo userInfo = new UserInfo();
userInfo.setUserName(userName);
userInfo.setPassword(password);
Integer result = userService.register(userInfo);
if (result == 1) {
log.info("test4 注册成功,userName:{},password:{}", userName, password);
throw new IOException();
}
return "注册成功";
}
}
执行请求后,尽管抛出受检异常,因配置了
rollbackFor = Exception.class,事务依然会回滚。
抛出非受查异常时
@RequestMapping("/test")
@RestController
@Slf4j
public class TestController {
private final UserService userService;
@Autowired
public TestController(UserService userService) {
this.userService = userService;
}
@Transactional
@RequestMapping("/test3")
public String test3(String userName, String password) {
UserInfo userInfo = new UserInfo();
userInfo.setUserName(userName);
userInfo.setPassword(password);
Integer result = userService.register(userInfo);
if (result == 1) {
log.info("test3 注册成功,userName:{},password:{}", userName, password);
throw new RuntimeException();
}
return "注册成功";
}
}
执行请求后,抛出
RuntimeException,默认触发回滚。
抛出受查异常时
@RequestMapping("/test")
@RestController
@Slf4j
public class TestController {
private final UserService userService;
@Autowired
public TestController(UserService userService) {
this.userService = userService;
}
@Transactional
@RequestMapping("/test2")
public String test2(String userName, String password) throws IOException {
UserInfo userInfo = new UserInfo();
userInfo.setUserName(userName);
userInfo.setPassword(password);
Integer result = userService.register(userInfo);
if (result == 1) {
log.info("test2 注册成功,userName:{},password:{}", userName, password);
throw new IOException();
}
return "注册成功";
}
}
执行请求后,抛出受检异常
IOException,默认不触发回滚(除非配置rollbackFor)。
2.2 isolation
**作用:**用于指定事务的隔离级别。
- Isolation.DEFAULT:使用底层数据库默认的隔离级别。
- Isolation.READ_UNCOMMITTED:读未提交。
- Isolation.READ_COMMITTED:读已提交。
- Isolation.REPEATABLE_READ:可重复读。
- Isolation.SERIALIZABLE:串行化。
2.3 propagation
**作用:**用于定义事务的传播行为,即当前事务方法被另一个事务方法调用时,事务应如何传播。Spring 提供了 7 种传播行为,均基于
Propagation枚举类实现。
2.3.1 Propagation.REQUIRED
默认传播行为。如果当前存在事务,则加入该事务;如果不存在事务,则新建一个事务。
2.3.2 Propagation.SUPPORTS
如果当前存在事务,则加入该事务;如果不存在事务,则以非事务方式执行。
2.3.3 Propagation.MANDATORY
强制要求当前存在事务并加入,否则抛出异常。
2.3.4 Propagation.REQUIRES_NEW
无论当前是否存在事务,都新建一个事务。新事务与当前事务独立,互不干扰。
2.3.5 Propagation.NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,则挂起该事务。
2.3.6 Propagation.NEVER
强制要求当前不能存在事务,否则抛出异常。
2.3.7 Propagation.NESTED
如果当前存在事务,则在嵌套事务中执行;如果不存在事务,则行为与
Propagation.REQUIRED相同。嵌套事务的回滚不影响外部事务,但外部事务回滚会导致嵌套事务回滚 (适用于需要部分回滚的场景)。


