java jdbc 中 savepoint 支持事务内局部回滚,需先调用 setautocommit(false),再用 setsavepoint() 创建保存点,通过 rollback(savepoint) 回滚至指定点,提交或全量回滚后保存点自动失效。

Java JDBC 中通过 Savepoint 可以在事务中设置保存点,实现局部回滚(即回滚到某个中间状态,而非整个事务),适用于复杂业务中需要“分段控制回滚”的场景,比如批量操作中前几条成功、后续出错时只回滚出错部分。
获取数据库连接并关闭自动提交
使用 Savepoint 前必须手动管理事务,因此要先关闭连接的自动提交模式:
- 调用
connection.setAutoCommit(false)禁用自动提交 - 确保连接来自支持事务的数据库(如 MySQL、PostgreSQL、Oracle),且使用的是支持事务的存储引擎(如 MySQL 的 InnoDB)
- 若忘记关闭自动提交,
setSavepoint()不会报错,但后续rollback(savepoint)无效
创建和使用 Savepoint 对象
调用 connection.setSavepoint() 创建保存点,返回一个 Savepoint 实例。可选传入字符串名称便于识别(非必需):
Savepoint sp1 = conn.setSavepoint("before_insert_user");Savepoint sp2 = conn.setSavepoint(); // 匿名保存点- 一个事务中可创建多个保存点,它们按创建顺序形成栈式结构
- 保存点只在当前事务内有效;事务提交或完全回滚后,所有保存点自动失效
执行部分回滚(rollback to savepoint)
发生异常或需要撤销某段操作时,调用 connection.rollback(savepoint) 回滚到指定保存点,该保存点之后的更改被撤销,但之前的操作仍保留:
conn.rollback(sp1); // 回滚到 sp1,sp1 本身及其之前操作不受影响- 注意:回滚到某个保存点后,该保存点之后创建的其他保存点(如 sp2、sp3)将自动失效,不可再用于 rollback
- 若需继续使用新保存点,需重新调用
setSavepoint() - 示例场景:插入用户 A 成功 → 设保存点 sp1 → 插入用户 B 失败 → 回滚到 sp1 → 用户 A 仍存在,B 的数据被丢弃
提交事务与清理保存点
事务最终需显式提交或回滚,保存点不会影响最终提交行为:
- 调用
conn.commit()提交全部未回滚的修改(包括保存点前后的有效操作) - 调用
conn.rollback()(无参)则彻底回滚整个事务,所有保存点失效 - JDBC 规范不要求手动释放保存点,事务结束(commit/rollback)后自动清除
- 不建议在同一个事务中反复创建大量保存点,可能带来轻微资源开销(尤其在某些数据库驱动中)
只要连接支持事务、自动提交已关闭、保存点创建和回滚位置逻辑清晰,用 Savepoint 实现部分回滚并不复杂,但容易因忽略 setAutoCommit(false) 或误用保存点顺序而失效。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











