百科 / SQL 状态码 / Class 25 无效的事务状态
25P04 transaction_timeout
事务超时
ERROR 已实测 详解 实测通过
- 条件名
transaction_timeout- 宏名称
ERRCODE_TRANSACTION_TIMEOUT- 最早已知存在
- 17.0
- 状态
- 有效
手册收录:17、18、19、20。此处仅表示同版本手册收录,运行证据仍以原核验构建为准。
版本覆盖
版本条依据已采样构建显示;灰色版本可能尚未采样,悬停可查看。手册链接随版本选择,源码和运行证据保持原核验构建。
25P04 — 事务超时(transaction_timeout)
速览 {#at-a-glance}
25P04 是 transaction_timeout 触发的 FATAL 条件,覆盖显式 BEGIN 事务和由单条语句隐式启动的事务。选定的 18.6 案例使用 300 ms;PG10 因设置不可用而在源码/版本预检阶段跳过,不会探测未知设置。另有 PG16.15/PG17.11 的版本边界对照:PG16 返回设置不可用的 42704,PG17 实际产生 FATAL 25P04;该对照独立于选定基础案例。
含义 {#meaning}
transaction_timeout 限制显式或隐式事务的存活时间,包括事务打开期间执行或等待的时间。触发后 PostgreSQL 发出 terminating connection due to transaction timeout 并终止会话。它不同于只中止一条语句的 statement_timeout,也不同于只覆盖客户端在开放事务中空闲时间的 idle_in_transaction_session_timeout。若 transaction_timeout 小于或等于其中任一设置,较长的超时会被忽略;预备事务不受此设置约束。
诊断 {#diagnosis}
在支持该设置的服务器上,先在目标会话自身检查有效的 SHOW transaction_timeout、SHOW statement_timeout 和 SHOW idle_in_transaction_session_timeout。控制连接上的 SHOW 或 pg_settings 反映的是观察者后端,不能用来确认另一个会话实际通过 SET 得到的值。再从控制连接查看 pg_stat_activity 的 pid、application_name、state、xact_start、state_change、query_start、query 等字段,定位所属应用或连接池,并判断事务是在执行还是空闲。按 backend PID、SQLSTATE 25P04、error_severity = FATAL 和精确报文匹配日志收集器记录。选定的 18.6 运行中驱动也暴露了 25P04,原连接已关闭;新的连接成功执行 SELECT 1。PG10 在发送 SET transaction_timeout 之前就由最低版本预检跳过。
处理 {#response}
丢弃已终止的会话并重连。对合法的长事务,可缩短工作、拆分工作单元或提高有效超时以控制在预算内;不要为了掩盖错误而降低超时。只有部署明确接受取消该保护时才设为 0。服务器关闭终止的会话时会在退出前回滚开放且尚未完成的事务;死亡连接不能再接收 ROLLBACK。已知尚未在该会话上提交的事务,不能通过该连接恢复。若另一种网络故障使客户端无法确定 COMMIT 是否到达服务器,应从新连接对账业务结果再重试;选定案例没有发送提交,不能据此声称存在这种不确定性。本批 PG10 没有兼容设置。
FATAL 报文 {#messages}
服务器源码固定报出 terminating connection due to transaction timeout,严重级别为 FATAL;原连接会被终止。
实测诊断 {#observed}
18.6 (Homebrew) / latest:FATAL SQLSTATE 25P04;主报文 terminating connection due to transaction timeout;backend PID 30576;原连接已关闭 True;CSV 日志 25P04;JSON 日志 25P04;新连接探测 1。
10.21 (Debian 10.21-1.pgdg90+1) / pg10:案例 not_applicable(最低版本预检;未探测该目标不支持的设置)。
单独的边界对照:16.15 / pg16 因设置不可用返回 42704 并保持 IDLE,因此不计作 25P04 覆盖;17.11 / pg17 在 300 ms 后由 PID 73 产生 FATAL 25P04,CSV 与 JSON 都记录 FATAL 25P04,原连接关闭,新连接为 IDLE。这些记录不计入选定基础案例。
代表案例 {#case}
下列 SQL 片段不是一次性粘贴脚本:在测试连接上执行设置、PID 和 BEGIN 后停止发送查询,由独立观察连接或日志收集器等待 FATAL;原连接终止后,另开新连接执行最后的探测。运行器从共享语句清单(registry)读取这些语句,完整断言、日志收集器关联、环境和清理见 案例导出。
-- set_timeout
SET transaction_timeout = '300ms';
-- backend_pid
SELECT pg_backend_pid();
-- begin
BEGIN;
-- probe
SELECT 1;
上述片段的 SQLSTATE、诊断、状态和修复断言来自共享语句清单(registry)(SHA-256 d05a26e56716c5c8c178f741843e6b14be87423ec9d1eb1a026ff67a57ce4658);结构化证据。
作者证据 ID:identity、timeout-path、runtime、runtime.version-boundary。选定基础运行记录:runtime.25P04-batch2c-latest-20260909.latest。单独的边界记录:runtime.25P04-boundary-pg16-20260909.pg16 和 runtime.25P04-boundary-pg17-20260909.pg17。
单独的边界对照已经记录了可用性结果:PG16 返回 42704,PG17 继续并实际产生 FATAL 25P04。这个边界块是分支说明,不能整块一次性粘贴执行。在 PG16 上先执行 SHOW transaction_timeout;得到预期的 42704 后,如需证明连接仍健康,应在同一连接执行 SELECT 1,然后停止,跳过 SET transaction_timeout、BEGIN 和等待超时。在 PG17 或更高版本上,只有 SHOW 成功后才在目标连接执行 SET transaction_timeout、记录 PID 并执行 BEGIN;随后停止发送查询,由观察连接或日志收集器等待旧连接出现 FATAL 并关闭,最后只在新连接上执行探测。这些边界记录用于诊断对照,不增加选定基础案例数量。
-- availability_probe
SHOW transaction_timeout;
-- set_timeout
SET transaction_timeout = '300ms';
-- backend_pid
SELECT pg_backend_pid();
-- begin
BEGIN;
-- probe
SELECT 1;
版本与边界 {#versions}
锁定目录首次观察到 transaction_timeout 为 17.0。选定的 18.6 案例以 CSV/JSON 日志收集证据和新连接探测通过。单独的 PG17.11 边界案例实际记录了 FATAL 25P04,PG16.15 则记录设置不可用的 42704;两者都不替代选定基础运行。PG10 是真实的 not_applicable 最低版本预检跳过:handler 不会发送或探测未知设置,因此这不构成更早版本边界证据。
相关 {#related}
25P03 事务中空闲超时、40001 可串行化失败、57014 查询取消。
来源 {#sources}
src.errcodes.18.6(SHA-2566e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)src.calls.REL_18_6—raw/calls/REL_18_6.jsonl(SHA-2569ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)src.postgres.18.6(SHA-2569fb62275b1badf94d01ab351337b60410cd9b3ab1fe63fa9f23d6d2185a21061)src.config.18.6(SHA-256ffca322c15315ba670733d6b320f23cbba7374db0d18937298ffc07b58799ef6) · official documentationdoc.monitoring.18.6(SHA-25606b147f8d966fe46821871703ffcee8a3449cc3f7de5b64b9177f48569fe96f6) · 官方监控文档src.system_views.18.6(SHA-256418f4ae7472fe0742e6fbdc7a055581602c5131e082aa6f17e2c7269bf711972) · 官方pg_settings文档doc.protocol.18.6(SHA-256745339e07ebbc2bb67d98b258e25772ada644ef26011e3cd6b3fcbb435235f89) · 官方协议文档
来源
- 上游源码 doc/src/sgml/monitoring.sgml 第 706–875 行
- 上游源码 doc/src/sgml/protocol.sgml 第 61–65 行
- 上游源码 doc/src/sgml/config.sgml 第 10252–10347 行
- 上游源码 src/backend/utils/errcodes.txt
- 上游源码 src/backend/tcop/postgres.c 第 3473–3501 行
- 上游源码 src/backend/catalog/system_views.sql 第 604–605 行
- 核验材料 raw/calls/REL_18_6.jsonl
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
25P04 is transaction_timeout in Class 25.
-
ProcessInterrupts emits FATAL 25P04 when an explicit or implicitly started transaction exceeds transaction_timeout.
-
The selected PostgreSQL 18.6 case received FATAL 25P04 for the exact backend PID and recovered only by opening a fresh connection; the PG10 case is not applicable.
-
The fixed monitoring documentation defines pg_stat_activity as one row per server process with current activity, including xact_start and state_change; pg_settings is defined over pg_show_all_settings for the current backend. Capture timeout settings on the timed session itself, because SHOW or pg_settings on an observer connection cannot establish another backend's effective SET value.
-
The fixed protocol documentation states that when the backend closes a connection it rolls back any open incomplete transaction before exiting; the driver cannot send a later ROLLBACK on that closed session.
-
On the fixed availability-boundary registry case, PostgreSQL 16.15 rejects SHOW transaction_timeout with 42704 and remains IDLE, while PostgreSQL 17.11 receives FATAL 25P04 after a 300 ms timeout in an idle-in-transaction session; the original session closes and a fresh connection is IDLE.
运行记录
| 目标 | 服务器版本 | 结果 | 覆盖案例 |
|---|---|---|---|
| latest | 18.6 (Homebrew) | passed | 案例:transaction_timeout |
| pg10 | 10.21 (Debian 10.21-1.pgdg90+1) | not_applicable | 案例:transaction_timeout |
| pg16 The case passed its availability assertions, but this target does not have the setting. The 42704 probe is retained as a version comparison and is not counted as a 25P04 runtime. |
16.15 (Debian 16.15-1.pgdg13+2) | not_applicable | 案例:transaction_timeout_version_boundary |
| pg17 This separate PG17.11 boundary case demonstrates the natural FATAL path and fresh-session recovery; it does not replace or inflate the selected base 18.6 case. |
17.11 (Debian 17.11-1.pgdg13+2) | passed | 案例:transaction_timeout_version_boundary |
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
terminating connection due to transaction timeout
来源: 来源:src/backend/tcop/postgres.c @ REL_18_6
适用范围:This is a static FATAL message; the driver may expose or omit SQLSTATE depending on client stack.
可复现案例
在一次性实例上执行过的场景。其中 2 个附有可执行 SQL,正文相应小节里给出。
transaction_timeout PG 18 有 SQL
前置条件
- A runner-owned disposable target is provisioned.
触发
On a server supporting transaction_timeout, set it, BEGIN, wait, and probe the terminated session.
断言
- The original session is terminated by the timeout when supported
- The collector records FATAL 25P04 for the matching backend PID
- A fresh connection can execute SELECT 1
- PG10 is explicitly not applicable
处置
Use the state-specific recovery documented on the page; do not reuse a terminated connection.
清理
Drop the case schema with an owner connection.
transaction_timeout_version_boundary PG 16 / 17 有 SQL
前置条件
- A disposable PostgreSQL 16 or 17 target
触发
Probe transaction_timeout on PG16; on PG17 set it, BEGIN, wait, and probe the terminated session.
断言
- PG16 records the actual unsupported-setting diagnostic and recovers
- PG17 records exact FATAL 25P04 collector fields and a registry-based fresh connection probe
处置
Treat PG16 as unsupported for this setting; for PG17 use a fresh connection after the FATAL and determine unfinished work from the application transaction boundary.
清理
Drop the case schema with an owner connection.
同类 SQL 状态码
| 状态码 | 条件名 | 宏名称 | 严重等级 | 版本 |
|---|---|---|---|---|
| 25000 | invalid_transaction_state | ERRCODE_INVALID_TRANSACTION_STATE |
ERROR | 7.4 起已知 |
| 事务状态无效的类别码,多见于内部状态检查。 | 有效 | |||
| 25001 | active_sql_transaction | ERRCODE_ACTIVE_SQL_TRANSACTION |
ERROR | 7.4 起已知 |
| 命令不能在活动事务块中执行,如 VACUUM。 | 有效 | |||
| 25002 | branch_transaction_already_active | ERRCODE_BRANCH_TRANSACTION_ALREADY_ACTIVE |
ERROR | 7.4 起已知 |
| 分支事务已经活动,范围窄于 25001。 | 有效 | |||
| 25003 | inappropriate_access_mode_for_branch_transaction | ERRCODE_INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION |
ERROR | 7.4 起已知 |
| 分支事务使用了不适用的访问模式。 | 有效 | |||
| 25004 | inappropriate_isolation_level_for_branch_transaction | ERRCODE_INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION |
ERROR | 7.4 起已知 |
| 分支事务使用了不适用的隔离级别。 | 有效 | |||
| 25005 | no_active_sql_transaction_for_branch_transaction | ERRCODE_NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION |
ERROR | 7.4 起已知 |
| 分支事务缺少活动的 SQL 事务。 | 有效 | |||
| 25006 | read_only_sql_transaction | ERRCODE_READ_ONLY_SQL_TRANSACTION |
ERROR | 7.4 起已知 |
| 命令试图在只读事务中写入数据。 | 有效 | |||
| 25007 | schema_and_data_statement_mixing_not_supported | ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED |
ERROR | 7.4 起已知 |
| 事务中不支持混合模式语句与数据语句。 | 有效 | |||
| 25008 | held_cursor_requires_same_isolation_level | ERRCODE_HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL |
ERROR | 7.4 起已知 |
| 持有游标要求与操作相同的事务隔离级别。 | 有效 | |||
| 25P01 | no_active_sql_transaction | ERRCODE_NO_ACTIVE_SQL_TRANSACTION |
ERROR | 7.4 起已知 |
| 操作需要活动事务块,如自动提交下的 SAVEPOINT。 | 有效 | |||
| 25P02 | in_failed_sql_transaction | ERRCODE_IN_FAILED_SQL_TRANSACTION |
ERROR | 7.4 起已知 |
| 事务已失败,后续语句被拒绝直到 ROLLBACK。 | 有效 | |||
| 25P03 | idle_in_transaction_session_timeout | ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT |
ERROR | 9.6.0 起已知 |
| 会话在开放事务中空闲超时,被服务器终止。 | 有效 | |||
| 25P04 | transaction_timeout | ERRCODE_TRANSACTION_TIMEOUT |
ERROR | 17.0 起已知 |
| 事务运行超过 transaction_timeout 被终止。 | 有效 | |||