文档 / SQL 状态码 / Class 3B 保存点异常
3B001 invalid_savepoint_specification
保存点说明无效
ERROR 已实测 参考 实测通过
- 条件名
invalid_savepoint_specification- 宏名称
ERRCODE_S_E_INVALID_SPECIFICATION- 启用版本
- 8.0
- 状态
- 活跃
版本覆盖
速览
3B001 表示保存点操作引用了当前事务层级中不存在的保存点。它不同于 25P01:后者表示根本没有活动事务块。
含义
当 ROLLBACK TO SAVEPOINT 或相关操作无法在当前保存点栈中找到名称时,事务管理器会发出 3B001。PG18 源码模板包含名称;PG10 源码仍使用较早的 no such savepoint 措辞。缺失名称是事务结构问题,不是表数据冲突。
诊断
保存 SQLSTATE、主报文、事务状态和完整保存点序列。检查拼写、保存点是否已经 RELEASE,以及嵌套过程或子事务是否改变了当前层级。显式事务中的 ERROR 会令连接处于 INERROR;回滚之前不要在那里继续执行目录查询或修复 SQL。
处理
回滚失败块,开启新的显式事务,并建立名称和嵌套层级都明确的保存点。如果希望保留部分工作,应在风险语句前建立正确名称的保存点,并只回滚到已存在的标记;错误发生后不能凭空恢复缺失标记。重试应视为新的事务计划,并保留业务幂等检查。
可复现案例
在一次性实例上执行过的场景。其中 1 个附有可执行 SQL,正文相应小节里给出。
invalid_savepoint_recovery PG 10 / 18 有 SQL
前置条件
- A runner-owned disposable target is provisioned.
触发
Inside a valid explicit transaction, roll back to a savepoint name that was never established, then rollback and establish a valid savepoint.
断言
- SQLSTATE is 3B001
- The diagnostic identifies the missing savepoint
- The failed block is INERROR until ROLLBACK
- A valid SAVEPOINT/RELEASE/COMMIT succeeds afterward
处置
Verify the savepoint name and nesting level; rollback the failed block before issuing a new savepoint sequence.
清理
Drop the case schema with an owner connection.
报文
18.6 固定源码包含 savepoint "%s" does not exist 及当前层级的相关变体;选定 PG10 输出为 no such savepoint。这些是有源码依据的版本/调用差异,应根据 3B001 和事务状态处理,不要依赖单一英文完整报文。
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
savepoint "%s" does not exist
来源:src/backend/access/transam/xact.c @ REL_18_6
适用范围:The name is dynamic.
no such savepoint
来源:src/backend/access/transam/xact.c @ REL_10_23
适用范围:PG10 wording omits the savepoint name.
代表案例
verify/cases/3B001/snippets.json(SHA-256 595ce7692e34d36cc31df94c65c7040ee9bc4558fa887c23b56ba3187d235deb)包含显式 BEGIN、已存在的 present 保存点、ROLLBACK TO SAVEPOINT missing,以及回滚后的修复序列。见公开案例导出和结构化证据。
BEGIN;
SAVEPOINT present;
ROLLBACK TO SAVEPOINT missing;
ROLLBACK;
BEGIN;
SAVEPOINT present;
RELEASE SAVEPOINT present;
COMMIT;
运行器使用 autocommit 只是为了让 registry 中的 BEGIN/ROLLBACK/COMMIT 边界完全显式;它断言缺失标记后是 INERROR,恢复提交后是 IDLE。
选定案例在 PostgreSQL 18.6 和 10.21 观察到 3B001。PG18 报 savepoint "missing" does not exist,PG10 报 no such savepoint;两者都让显式事务在 ROLLBACK 前保持 INERROR,之后合法保存点序列可以提交。
版本
目录从 8.0.0 或更早边界到正式快照都记录了 3B001。选定的 18.6 与 10.21 运行证明 SQLSTATE 和恢复边界;主要报文则从旧版泛化措辞变为包含保存点名称的模板。
来源
- 上游源码 doc/src/sgml/ref/savepoint.sgml
- 上游源码 src/backend/utils/errcodes.txt
- 上游源码 src/backend/access/transam/xact.c 第 3914–3916 行
- 上游源码 src/backend/access/transam/xact.c 第 4482–4484 行
- 核验材料 raw/calls/REL_18_6.jsonl
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
3B001 is the invalid_savepoint_specification condition in Class 3B.
-
RollbackToSavepoint emits a missing-savepoint error when the named savepoint is not present at the current level.
-
A failed ROLLBACK TO SAVEPOINT leaves the explicit transaction in error; ROLLBACK ends that block before a new savepoint sequence.
-
The selected 3B001 case passed on PostgreSQL 18.6 and 10.21 with the structured SQLSTATE, transaction-state, and repair assertions recorded in the runtime entries.
运行记录
| 目标 | 服务器版本 | 结果 | 覆盖案例 |
|---|---|---|---|
| latest | 18.6 (Homebrew) | passed | invalid_savepoint_recovery |
| pg10 | 10.21 (Debian 10.21-1.pgdg90+1) | passed | invalid_savepoint_recovery |
同类 SQL 状态码
| 状态码 | 条件名 | 宏名称 | 严重等级 | 版本 |
|---|---|---|---|---|
| 3B000 | savepoint_exception | ERRCODE_SAVEPOINT_EXCEPTION |
ERROR | 8.0 |
| 保存点异常的类别码,具体失败见 3B001。 | 活跃 | |||
| 3B001 | invalid_savepoint_specification | ERRCODE_S_E_INVALID_SPECIFICATION |
ERROR | 8.0 |
| 引用了当前事务中不存在的保存点。 | 活跃 | |||