3B001 — invalid_savepoint_specification(保存点说明无效)
引用了当前事务中不存在的保存点。
英文手册覆盖始于 PostgreSQL 8.1. 来源历史与运行验证各自保留独立版本边界。
当前阅读 PG 18·选择有来源记录的版本
- aliases
- 未知
- class name
- Savepoint Exception
- condition name
- invalid_savepoint_specification
- lang
- en
- sqlstate
- 3B001
版本定义 PG 18
3B001 — invalid_savepoint_specification(保存点说明无效)
速览 {#at-a-glance}
3B001 表示保存点操作引用了当前事务层级中不存在的保存点。它不同于 25P01:后者表示根本没有活动事务块。
含义 {#meaning}
当 ROLLBACK TO SAVEPOINT 或相关操作无法在当前保存点栈中找到名称时,事务管理器会发出 3B001。PG18 源码模板包含名称;PG10 源码仍使用较早的 no such savepoint 措辞。缺失名称是事务结构问题,不是表数据冲突。
诊断 {#diagnosis}
保存 SQLSTATE、主报文、事务状态和完整保存点序列。检查拼写、保存点是否已经 RELEASE,以及嵌套过程或子事务是否改变了当前层级。显式事务中的 ERROR 会令连接处于 INERROR;回滚之前不要在那里继续执行目录查询或修复 SQL。
处理 {#response}
回滚失败块,开启新的显式事务,并建立名称和嵌套层级都明确的保存点。如果希望保留部分工作,应在风险语句前建立正确名称的保存点,并只回滚到已存在的标记;错误发生后不能凭空恢复缺失标记。重试应视为新的事务计划,并保留业务幂等检查。
报文 {#messages}
18.6 固定源码包含 savepoint "%s" does not exist 及当前层级的相关变体;选定 PG10 输出为 no such savepoint。这些是有源码依据的版本/调用差异,应根据 3B001 和事务状态处理,不要依赖单一英文完整报文。
代表案例 {#case}
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,之后合法保存点序列可以提交。
版本 {#versions}
目录从 8.0.0 或更早边界到正式快照都记录了 3B001。选定的 18.6 与 10.21 运行证明 SQLSTATE 和恢复边界;主要报文则从旧版泛化措辞变为包含保存点名称的模板。
相关 {#related}
可对照3B000 保存点异常以及没有事务块时的25P01 无活动 SQL 事务。
来源 {#sources}
src.errcodes.18.6(SHA-2566e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)src.xact.18.6(SHA-25675b012c0b047d1dc905a30975c244beec366e45eac0dbf109fd21bcd611a8e39)src.xact.10.23(SHA-2569120bd418bd0f18e3f1065a3772c92ff68f3be54e1a8c6d415043197f6daa47c)SAVEPOINT 官方文档· 本地调用扫描src.calls.REL_18_6(SHA-2569ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)
比较版本
SQLSTATE 证据与已记录的运行版本
cases · invalid_savepoint_recovery
{
"assertions": [
"SQLSTATE is 3B001",
"The diagnostic identifies the missing savepoint",
"The failed block is INERROR until ROLLBACK",
"A valid SAVEPOINT/RELEASE/COMMIT succeeds afterward"
],
"case_id": "invalid_savepoint_recovery",
"cleanup": "Drop the case schema with an owner connection.",
"has_snippet": true,
"position": 0,
"preconditions": [
"A runner-owned disposable target is provisioned."
],
"repair": "Verify the savepoint name and nesting level; rollback the failed block before issuing a new savepoint sequence.",
"trigger": "Inside a valid explicit transaction, roll back to a savepoint name that was never established, then rollback and establish a valid savepoint.",
"versions": [
"10",
"18"
]
}claims · identity
{
"claim_id": "identity",
"limits": "The class-level 3B000 entry is separate from this specific condition.",
"method": "Read the fixed errcodes.txt row and macro mapping.",
"position": 0,
"runtime": [],
"sources": [
"src.errcodes.18.6"
],
"statement": "3B001 is the invalid_savepoint_specification condition in Class 3B."
}claims · savepoint-path
{
"claim_id": "savepoint-path",
"limits": "PG10 uses the older no such savepoint wording; the SQLSTATE and state transition are the stable facts here.",
"method": "Trace ERRCODE_S_E_INVALID_SPECIFICATION in xact.c.",
"position": 1,
"runtime": [],
"sources": [
"src.xact.18.6",
"src.calls.REL_18_6"
],
"statement": "RollbackToSavepoint emits a missing-savepoint error when the named savepoint is not present at the current level."
}claims · recovery
{
"claim_id": "recovery",
"limits": "A valid savepoint at another nesting level is a different case.",
"method": "Run the shared explicit BEGIN/SAVEPOINT/ROLLBACK case and inspect transaction status.",
"position": 2,
"runtime": [],
"sources": [
"doc.savepoint.18.6"
],
"statement": "A failed ROLLBACK TO SAVEPOINT leaves the explicit transaction in error; ROLLBACK ends that block before a new savepoint sequence."
}claims · runtime
{
"claim_id": "runtime",
"limits": "This covers the selected mechanism only, not all source callers or all driver/pool behavior.",
"method": "Read the selected runner summaries and raw outputs tied to the shared snippet registry.",
"position": 3,
"runtime": [],
"sources": [
"runtime.3B001-batch34-20260909.latest",
"runtime.3B001-batch34-20260909.pg10"
],
"statement": "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."
}messages · message.savepoint-modern
{
"limits": "The name is dynamic.",
"message_id": "message.savepoint-modern",
"path": "",
"position": 0,
"raw": {
"id": "message.savepoint-modern",
"limits": "The name is dynamic.",
"primary_template": "savepoint \"%s\" does not exist",
"severity_source": "ERROR",
"sources": [
"src.xact.18.6"
],
"sqlstate": "3B001"
},
"severity": "ERROR",
"sources": [
"src.xact.18.6"
],
"templates": [
{
"kind": "primary",
"literal": "savepoint \" \" does not exist",
"position": 0,
"role": "",
"template": "savepoint \"%s\" does not exist"
}
]
}messages · message.savepoint-pg10
{
"limits": "PG10 wording omits the savepoint name.",
"message_id": "message.savepoint-pg10",
"path": "",
"position": 1,
"raw": {
"id": "message.savepoint-pg10",
"limits": "PG10 wording omits the savepoint name.",
"primary_template": "no such savepoint",
"severity_source": "ERROR",
"sources": [
"src.xact.10.23"
],
"sqlstate": "3B001"
},
"severity": "ERROR",
"sources": [
"src.xact.10.23"
],
"templates": [
{
"kind": "primary",
"literal": "no such savepoint",
"position": 0,
"role": "",
"template": "no such savepoint"
}
]
}runtimes · runtime.3B001-batch34-20260909.latest · 18.6 (Homebrew) · passed
{
"cases": [
"invalid_savepoint_recovery"
],
"limits": "",
"position": 0,
"raw": {
"case_manifest": {
"path": "verify/cases/3B001/cases.json",
"sha256": "084e2bb92c6ed5388c30ece2406512434e8134c17880a2c8b8cdecdaca5001bc"
},
"cases": [
"invalid_savepoint_recovery"
],
"id": "runtime.3B001-batch34-20260909.latest",
"observed": {
"connection_autocommit": true,
"primary": "savepoint \"missing\" does not exist",
"repair": {},
"severity": "ERROR",
"sqlstate": "3B001",
"statuses": {
"after_error": "INERROR",
"after_repair": "IDLE",
"after_rollback": "IDLE"
}
},
"raw": "verify/results/3B001-batch34-20260909/latest/raw.jsonl",
"raw_sha256": "f01798df2d267371cc2eca0422cf862edf0c30a58edefa138b5a8c2bd451dab5",
"run_id": "3B001-batch34-20260909",
"server_version": "18.6 (Homebrew)",
"snippet_registry": {
"path": "verify/cases/3B001/snippets.json",
"sha256": "595ce7692e34d36cc31df94c65c7040ee9bc4558fa887c23b56ba3187d235deb"
},
"status": "passed",
"summary": "verify/results/3B001-batch34-20260909/latest/summary.json",
"summary_sha256": "8299597b2f31d38a52997a7386c65d71a3dd433a8bf69583bc1f55f6c5e67b95",
"target": "latest"
},
"run_id": "3B001-batch34-20260909",
"runtime_id": "runtime.3B001-batch34-20260909.latest",
"server_version": "18.6 (Homebrew)",
"status": "passed",
"target": "latest"
}runtimes · runtime.3B001-batch34-20260909.pg10 · 10.21 (Debian 10.21-1.pgdg90+1) · passed
{
"cases": [
"invalid_savepoint_recovery"
],
"limits": "",
"position": 1,
"raw": {
"case_manifest": {
"path": "verify/cases/3B001/cases.json",
"sha256": "084e2bb92c6ed5388c30ece2406512434e8134c17880a2c8b8cdecdaca5001bc"
},
"cases": [
"invalid_savepoint_recovery"
],
"id": "runtime.3B001-batch34-20260909.pg10",
"observed": {
"connection_autocommit": true,
"primary": "no such savepoint",
"repair": {},
"severity": "ERROR",
"sqlstate": "3B001",
"statuses": {
"after_error": "INERROR",
"after_repair": "IDLE",
"after_rollback": "IDLE"
}
},
"raw": "verify/results/3B001-batch34-20260909/pg10/raw.jsonl",
"raw_sha256": "66ae381dc1edbb309a234751738e015d5bd34b38777f7ae66e7b6eeee549ce91",
"run_id": "3B001-batch34-20260909",
"server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
"snippet_registry": {
"path": "verify/cases/3B001/snippets.json",
"sha256": "595ce7692e34d36cc31df94c65c7040ee9bc4558fa887c23b56ba3187d235deb"
},
"status": "passed",
"summary": "verify/results/3B001-batch34-20260909/pg10/summary.json",
"summary_sha256": "7e4de60ee83cc2e565050d93648c16006a266d3f584f8d1b096aef89b546ebe2",
"target": "pg10"
},
"run_id": "3B001-batch34-20260909",
"runtime_id": "runtime.3B001-batch34-20260909.pg10",
"server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
"status": "passed",
"target": "pg10"
}sources · src.errcodes.18.6
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "upstream_source",
"location": "",
"path": "src/backend/utils/errcodes.txt",
"position": 0,
"sha256": "6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba",
"source_id": "src.errcodes.18.6",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt"
}sources · src.calls.REL_18_6
{
"commit": "",
"docs_url": "",
"kind": "local_artifact",
"location": "",
"path": "raw/calls/REL_18_6.jsonl",
"position": 1,
"sha256": "9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf",
"source_id": "src.calls.REL_18_6",
"tag": "",
"url": ""
}sources · src.xact.18.6
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "upstream_source",
"location": "",
"path": "src/backend/access/transam/xact.c",
"position": 2,
"sha256": "75b012c0b047d1dc905a30975c244beec366e45eac0dbf109fd21bcd611a8e39",
"source_id": "src.xact.18.6",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/access/transam/xact.c#L4482-L4484"
}sources · src.xact.10.23
{
"commit": "02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4",
"docs_url": "",
"kind": "upstream_source",
"location": "",
"path": "src/backend/access/transam/xact.c",
"position": 3,
"sha256": "9120bd418bd0f18e3f1065a3772c92ff68f3be54e1a8c6d415043197f6daa47c",
"source_id": "src.xact.10.23",
"tag": "REL_10_23",
"url": "https://github.com/postgres/postgres/blob/02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4/src/backend/access/transam/xact.c#L3914-L3916"
}sources · doc.savepoint.18.6
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "https://www.postgresql.org/docs/18/sql-savepoint.html",
"kind": "upstream_source",
"location": "",
"path": "doc/src/sgml/ref/savepoint.sgml",
"position": 4,
"sha256": "aa6e167d373da6118249c87404a7b2ff8be8c7df790449814f1d9dc433bbd428",
"source_id": "doc.savepoint.18.6",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/doc/src/sgml/ref/savepoint.sgml"
}来源引用
定义来源
center · PostgreSQL 18 · english-manuals:3a16430ec0f037fb2cfa2359bc98bbd7c401b2ee0c9e32e01526e817cb825130
正文语言: zh-Hans · english-manuals:3a16430ec0f037fb2cfa2359bc98bbd7c401b2ee0c9e32e01526e817cb825130