百科 / 错误代码 / Class 25 事务状态无效
25P02 in_failed_sql_transaction
事务处于失败状态
ERROR 已实测 详解 实测通过
- 条件名
in_failed_sql_transaction- 宏名称
ERRCODE_IN_FAILED_SQL_TRANSACTION- 启用版本
- 7.4
- 状态
- 活跃
版本覆盖
速览
25P02 通常是第二个诊断,而不是根因。选定案例先因重复键返回 23505,随后 SELECT 在事务仍为 INERROR 时被 25P02 拒绝;必须先 ROLLBACK 才能有效重试。
含义
postgres.c 在再次规划普通命令前检查已中止事务状态,并报告 current transaction is aborted, commands ignored until end of transaction block。驱动会暴露对应的失败事务状态;原始错误仍是诊断锚点,25P02 表示该事务块已经不能继续执行普通业务语句。
诊断
先定位 25P02 之前的第一条语句错误,再记录两个诊断和连接事务状态。选定运行显示根错误 23505、随后 25P02;两次之后都为 INERROR,ROLLBACK 后为 IDLE,新的显式 BEGIN/COMMIT 成功提交有效行。检查根错误前是否建立了保存点:ROLLBACK TO SAVEPOINT 可以保留外层事务;没有保存点时必须结束整个失败事务块。连接池不能把 INERROR 会话交给下一个请求。
处理
第一条错误后停止发送业务语句,保留根 SQLSTATE 和详情。若事先建立的保存点仍可用,就回滚到该保存点并继续外层事务;否则执行 ROLLBACK,确认连接回到 IDLE,再开启新事务。应重新评估操作,不要盲目重放根语句。
可复现案例
在一次性实例上执行过的场景。其中 1 个附有可执行 SQL,正文相应小节里给出。
failed_transaction_recovery PG 10 / 18 有 SQL
前置条件
- A runner-owned disposable target is provisioned.
触发
Raise a root unique violation, then issue a query before ROLLBACK.
断言
- The root duplicate is 23505
- The follow-up command reports 25P02
- The failed transaction remains INERROR until ROLLBACK
- A new explicit transaction commits the repaired row
处置
Follow the explicit transaction or source boundary described by the case.
清理
Drop the case schema with an owner connection.
源码报文
固定主报文是 current transaction is aborted, commands ignored until end of transaction block。它描述前一条错误留下的事务状态,不能覆盖根错误的 SQLSTATE、DETAIL 或约束身份。
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
current transaction is aborted, commands ignored until end of transaction block
来源:src/backend/tcop/postgres.c @ REL_18_6
适用范围:The message is secondary to the earlier statement error; errdetail_abort may add context.
实测诊断
18.6 (Homebrew) / latest:根 SQLSTATE 23505;次级 SQLSTATE 25P02;根错误/次级诊断后均为 INERROR;回滚后 IDLE;行集 [[1, 'seed'], [2, 'repaired']]。
10.21 (Debian 10.21-1.pgdg90+1) / pg10:根 SQLSTATE 23505;次级 SQLSTATE 25P02;根错误/次级诊断后均为 INERROR;回滚后 IDLE;行集 [[1, 'seed'], [2, 'repaired']]。
代表案例
运行器从共享语句清单(registry)读取下列根错误、次级诊断、回滚和有效重试语句;完整断言、环境和清理见 案例导出。
-- create
CREATE TABLE items(id integer PRIMARY KEY, note text UNIQUE NOT NULL);
-- seed
INSERT INTO items VALUES (1, 'seed');
-- begin
BEGIN;
-- trigger
INSERT INTO items VALUES (2, 'seed');
-- followup
SELECT 1 AS ignored;
-- rollback
ROLLBACK;
-- repair_begin
BEGIN;
-- repair
INSERT INTO items VALUES (2, 'repaired');
-- commit
COMMIT;
-- verify
SELECT id, note FROM items ORDER BY id;
上述片段的 SQLSTATE、诊断、状态和修复断言来自共享语句清单(registry)(SHA-256 04da3240dcf3c03fe60d13715f8187350fadf5b8d1f10e5b837acd45289759cd);结构化证据。
作者证据 ID:identity, abort-state, runtime。选定运行记录:runtime.25P02-batch2-latest-20260909.latest, runtime.25P02-batch2-pg10-20260909.pg10。
版本与边界
选定的“重复键后出现 25P02”案例在 PostgreSQL 18.6 与 10.21 通过。它证明事务状态恢复,不表示可以原样重试重复键操作。
来源
- 上游源码 doc/src/sgml/libpq.sgml 第 2818–2835 行
- 上游源码 src/backend/utils/errcodes.txt
- 上游源码 src/backend/tcop/postgres.c 第 1127–1140 行
- 核验材料 raw/calls/REL_18_6.jsonl
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
25P02 is in_failed_sql_transaction in Class 25.
-
After an error aborts a transaction block, postgres.c rejects subsequent commands with 25P02 until COMMIT/ROLLBACK ends the block.
-
The selected case first raises 23505, then observes 25P02 while INERROR, rolls back to IDLE, and commits a valid row in a new explicit transaction on both targets.
运行记录
| 目标 | 服务器版本 | 结果 | 覆盖案例 |
|---|---|---|---|
| latest | 18.6 (Homebrew) | passed | failed_transaction_recovery |
| pg10 | 10.21 (Debian 10.21-1.pgdg90+1) | passed | failed_transaction_recovery |
同类错误代码
Class 25 事务状态无效 下的其他成员。
25000invalid_transaction_state25001active_sql_transaction25002branch_transaction_already_active25003inappropriate_access_mode_for_branch_transaction25004inappropriate_isolation_level_for_branch_transaction25005no_active_sql_transaction_for_branch_transaction25006read_only_sql_transaction25007schema_and_data_statement_mixing_not_supported25008held_cursor_requires_same_isolation_level25P01no_active_sql_transaction25P03idle_in_transaction_session_timeout25P04transaction_timeout