Java中需显式关闭自动提交、复用同一Connection、在catch业务异常时调用rollback(),finally中重置autocommit并关闭资源;推荐使用Spring @Transactional自动管理。

Java 中不能直接调用 rollback() 方法来“自动”回滚 MySQL 事务,必须由开发者显式控制事务边界,并在捕获业务异常后手动调用 Connection.rollback()。关键在于:事务不是自动感知业务逻辑的,你需要自己管理连接、关闭自动提交、捕获异常并触发回滚。
确保使用同一个 Connection 并关闭自动提交
MySQL 默认开启自动提交(autocommit=true),每条 SQL 都会立即生效。要支持回滚,必须先关闭它:
- 获取
Connection后立刻调用conn.setAutoCommit(false) - 整个业务操作(多条 SQL)必须复用这一个
Connection,不能中途换连接或用连接池未配置好的方式 - 示例:错误写法是每次 DAO 方法都从连接池取新连接,那样事务根本跨不了方法
在 catch 块中显式调用 rollback()
只要发生业务异常(比如参数校验失败、余额不足、唯一键冲突等),就要立即回滚,避免脏数据:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 把核心业务逻辑放在
try块中 - 在
catch (BusinessException | RuntimeException e)中调用conn.rollback() - 注意:不要只 catch
SQLException—— 业务异常通常不是 SQL 异常,而是你自定义的InsufficientBalanceException这类 - 回滚后建议记录日志,例如:
log.warn("事务已回滚,原因:{}", e.getMessage())
finally 中恢复 autocommit 并关闭资源
无论成功还是失败,都要释放连接并重置状态,否则连接可能被卡住或下次误用 autocommit 状态:
立即学习“Java免费学习笔记(深入)”;
- 在
finally块中调用conn.setAutoCommit(true)(可选但推荐) - 调用
conn.close()—— 如果用 HikariCP 等连接池,这只是归还连接,不是真正关闭 - 强烈建议使用 try-with-resources 管理
PreparedStatement和ResultSet,但Connection一般不由它管理(因需跨多个 Statement)
更稳妥的做法:用 Spring @Transactional(推荐)
纯 JDBC 手动控制容易出错(比如忘记 rollback、异常没捕获全)。Spring 的声明式事务能自动处理:
- 在 service 方法上加
@Transactional(rollbackFor = BusinessException.class) - 抛出指定的业务异常时,Spring 自动触发
rollback() - 底层仍基于同一
Connection和setAutoCommit(false),但无需手写模板代码 - 注意:异常必须抛出到代理层(不能在方法内吞掉),且默认只对
RuntimeException和Error回滚,检查型异常需显式声明rollbackFor

















