JDBC中保存点支持事务的部分回滚,需关闭自动提交;通过setSavepoint创建、rollback(Savepoint)回滚、releaseSavepoint释放;回滚后该点及后续保存点失效。

在 JDBC 中使用保存点(Savepoint)可以实现事务中的部分回滚,即回滚到某个中间状态而不影响之前已提交的操作。关键在于:必须在支持事务的数据库连接上操作,且连接不能处于自动提交模式(auto-commit = false),否则保存点无效。
创建和使用 Savepoint
调用 Connection.setSavepoint() 创建保存点,它返回一个 Savepoint 对象。该对象可在后续用于回滚到该点:
- 不传参时,数据库自动生成名称(如
SAVEPOINT SQL123); - 可传入字符串名,便于识别和调试(如
conn.setSavepoint("before_update")); - 同一个连接中可设置多个保存点,按创建顺序形成嵌套结构。
回滚到指定 Savepoint
使用 Connection.rollback(Savepoint) 回滚到某一点,注意:
- 该操作只撤销从该保存点之后执行的语句,之前的修改仍保留;
- 回滚后,该保存点及之后创建的所有保存点自动失效(不可再用);
- 例如:设了
sp1→ 执行插入 → 设sp2→ 执行更新 →rollback(sp1),则插入和更新都会被撤销。
释放 Savepoint(可选但推荐)
调用 Connection.releaseSavepoint(Savepoint) 主动释放保存点,作用是:
立即学习“Java免费学习笔记(深入)”;
- 告知数据库不再需要该保存点,有助于资源清理;
- 释放后若再用此保存点回滚会抛出
SQLException; - 通常在确认无需回滚时调用,比如业务逻辑正常走完、准备提交前。
完整示例片段
以下是一个典型用法(伪代码,省略异常处理和资源关闭):
conn.setAutoCommit(false);
Savepoint sp1 = conn.setSavepoint("insert_start");
stmt.executeUpdate("INSERT INTO orders ...");
<p>Savepoint sp2 = conn.setSavepoint("update_start");
stmt.executeUpdate("UPDATE stock SET qty = qty - 1 WHERE id = 100");</p><p>// 若库存不足,回滚到插入前
if (stockInsufficient) {
conn.rollback(sp1); // 插入也被撤销
} else {
conn.releaseSavepoint(sp1); // 不再需要 sp1
conn.commit();
}</p>


















