手动回滚事务的核心是调用TransactionStatus的setRollbackOnly()方法或PlatformTransactionManager的rollback()方法;在Spring中推荐使用TransactionTemplate.execute()回调内调用setRollbackOnly(),或在@Transactional方法中通过TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()标记回滚。

在 Java 中手动回滚事务,核心是获取当前事务的 TransactionStatus 对象,并调用其 setRollbackOnly() 方法(适用于 Spring 声明式事务),或直接调用底层事务管理器的回滚操作(如 JTA 或 JDBC)。最常用、推荐的方式是在 Spring 环境中通过编程式事务控制。
使用 TransactionTemplate 手动回滚
TransactionTemplate 是 Spring 提供的编程式事务模板,简洁安全,适合需要精细控制回滚时机的场景。
- 注入
TransactionTemplate(通常通过@Autowired) - 在业务逻辑中调用
execute(),并在回调内主动抛出异常或调用TransactionAspectSupport.currentTransactionStatus().setRollbackOnly() - 若只是想“标记回滚”,不抛异常,可在
TransactionCallbackWithoutResult中调用setRollbackOnly()
示例:
transactionTemplate.execute(status -> {
try {
// 执行数据库操作
userDao.save(user);
if (someCondition) {
status.setRollbackOnly(); // 标记当前事务为仅回滚
}
} catch (Exception e) {
status.setRollbackOnly();
throw e;
}
return null;
});
在 @Transactional 方法内触发回滚
当方法已标注 @Transactional,Spring 会自动管理事务。手动回滚只需让事务感知到“失败信号”:
- 默认情况下,未检查异常(
RuntimeException及其子类)会触发自动回滚 - 若需对受检异常(如
Exception)也回滚,需在注解中声明:@Transactional(rollbackFor = Exception.class) - 也可不依赖异常,直接调用:
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
注意:必须确保该方法运行在 Spring 代理上下文中(即不能是 this. 调用),否则 currentTransactionStatus() 会返回 null。
使用 PlatformTransactionManager 底层控制
适用于需要完全自定义事务生命周期的场景(如集成非 Spring 管理的数据源):
- 注入
PlatformTransactionManager - 调用
getTransaction()获取TransactionStatus - 执行业务逻辑后,根据条件调用
transactionManager.rollback(status) - 成功则调用
commit(status)
示例关键片段:
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
userDao.update(user);
if (needRollback) {
transactionManager.rollback(status);
return;
}
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
throw e;
}
常见误区提醒
手动回滚不是“撤销已执行的 SQL”,而是通知事务管理器在提交阶段放弃所有变更。因此:
- 回滚操作必须在事务尚未提交前调用,提交后调用无效
-
setRollbackOnly()不会立即释放数据库锁,直到事务真正结束(提交或回滚) - 嵌套事务中,内层标记回滚通常会导致外层也回滚(取决于传播行为,如
REQUIRES_NEW则隔离) - JDBC 原生事务需调用
connection.rollback(),但应避免混用 Spring 事务与裸 connection 控制
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











