Java事务回滚需依机制而定:JDBC中调用connection.rollback();Spring编程式事务用setRollbackOnly()或抛RuntimeException;声明式事务@Transaction默认仅对RuntimeException回滚,可配置rollbackFor。

Java 中没有直接叫 rollback() 的独立方法,事务回滚依赖于具体的事务管理机制。核心原则是:在捕获异常后,主动触发回滚操作——但具体怎么写,取决于你用的是 JDBC 原生、Spring 编程式事务,还是声明式事务(@Transactional)。
使用 JDBC 时手动控制 rollback
当你直接使用 Connection 管理事务,必须关闭自动提交,并在异常时显式调用 connection.rollback():
- 调用
connection.setAutoCommit(false)开启事务边界 - 正常执行 SQL 后,调用
connection.commit() - 发生异常时,必须在
catch或finally中调用connection.rollback()(注意判空和异常屏蔽)
示例关键片段:
Connection conn = null;
try {
conn = dataSource.getConnection();
conn.setAutoCommit(false);
// 执行 update/insert...
conn.commit();
} catch (SQLException e) {
if (conn != null) {
try {
conn.rollback(); // ⚠️ 关键回滚调用
} catch (SQLException rollbackEx) {
// 记录 rollback 失败日志
}
}
throw e;
} finally {
if (conn != null) {
try { conn.close(); } catch (SQLException ignored) {}
}
}
Spring 编程式事务中调用 rollback
使用 TransactionTemplate 时,不需手动 rollback——它会在抛出运行时异常(RuntimeException)时自动回滚;若想强制回滚,可抛出 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly():
- 推荐方式:让业务逻辑抛出未检查异常(如
RuntimeException),框架自动处理 - 特殊情况需手动标记回滚:调用
TransactionStatus.setRollbackOnly() - 注意:
setRollbackOnly()不会立即终止事务,只是标记“必须回滚”,后续 commit 会被忽略
示例:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
transactionTemplate.execute(status -> {
jdbcTemplate.update("INSERT INTO ...");
if (someCondition) {
status.setRollbackOnly(); // 主动标记回滚
return null;
}
return "success";
});
Spring 声明式事务(@Transactional)的回滚规则
这是最常用的方式。@Transactional 默认只对 未检查异常(RuntimeException 及其子类)和 Error 回滚;检查异常(如 Exception)默认 不回滚:
- 想让特定检查异常也触发回滚:用
@Transactional(rollbackFor = IOException.class) - 想排除某类异常不回滚(即使它是 RuntimeException):用
noRollbackFor = CustomException.class - 方法内
try-catch吞掉异常 → 事务不会感知异常 → 不会回滚(常见坑!)
正确写法示例:
@Transactional(rollbackFor = Exception.class)
public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
accountDao.withdraw(fromId, amount);
accountDao.deposit(toId, amount);
// 若这里抛出任何 Exception,事务都会回滚
}
注意事项与常见误区
事务回滚不是“写了 rollback 就一定生效”,以下细节决定成败:
- 数据库引擎必须支持事务(如 MySQL 的 InnoDB,MyISAM 不支持)
- 连接池配置需确保事务传播一致(避免 connection 被复用导致隔离问题)
- 自调用失效:同一个类内非 public 方法或 this.xxx() 调用,
@Transactional不生效 - rollbackOnly 后再抛异常仍会回滚,但不要依赖“双重保险”,逻辑应清晰明确
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










