文档 / SQL 状态码 / Class 25 事务状态无效
25P01 no_active_sql_transaction
没有活动 SQL 事务
ERROR 已实测 参考 实测通过
- 条件名
no_active_sql_transaction- 宏名称
ERRCODE_NO_ACTIVE_SQL_TRANSACTION- 启用版本
- 7.4
- 状态
- 活跃
版本覆盖
速览
25P01 表示操作需要活动 SQL 事务。选定案例在自动提交会话中发送 SAVEPOINT,得到精确错误且会话保持 IDLE;随后在 BEGIN 内重新执行并提交。
含义
源码把语句名填入 %s can only be used in transaction blocks;本文的 SAVEPOINT 路径严重级别为 ERROR。同一 SQLSTATE 还覆盖 COMMIT AND CHAIN/ROLLBACK AND CHAIN 的错误,以及无事务时 COMMIT/ROLLBACK 的警告,固定报文是 there is no transaction in progress。
诊断
执行 SAVEPOINT、RELEASE SAVEPOINT 或 ROLLBACK TO SAVEPOINT 前,先确认客户端已进入显式事务块。选定运行中失败的自动提交语句后仍为 IDLE;修复序列是 BEGIN、SAVEPOINT、RELEASE、COMMIT。
处理
创建保存点前先启动显式事务。若操作误发在事务块外,应修正客户端事务包装后重试;本自动提交错误没有遗留失败事务块,因此不需要回滚。
可复现案例
在一次性实例上执行过的场景。其中 1 个附有可执行 SQL,正文相应小节里给出。
savepoint_without_transaction PG 10 / 18 有 SQL
前置条件
- A runner-owned disposable target is provisioned.
触发
Run SAVEPOINT without BEGIN, then repeat inside an explicit block.
断言
- SQLSTATE is 25P01
- SAVEPOINT outside a block reports the no-active-transaction message
- An explicit BEGIN/SAVEPOINT/RELEASE/COMMIT repair succeeds
处置
Follow the explicit transaction or source boundary described by the case.
清理
Drop the case schema with an owner connection.
源码报文
xact.c 用 %s can only be used in transaction blocks 组装语句级报文;本案例把 %s 替换为 SAVEPOINT,严重级别为 ERROR。COMMIT AND CHAIN 与 ROLLBACK AND CHAIN 在无事务块时使用同一动态形式;无事务时的 COMMIT/ROLLBACK 则使用 WARNING 报文 there is no transaction in progress。
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
%s can only be used in transaction blocks
来源:src/backend/access/transam/xact.c @ REL_18_6
适用范围:The %s substitution is the statement name; the selected message is SAVEPOINT can only be used in transaction blocks.
there is no transaction in progress
来源:src/backend/access/transam/xact.c @ REL_18_6
适用范围:Used by no-transaction COMMIT/ROLLBACK branches; it is not the selected SAVEPOINT ERROR.
实测诊断
18.6 (Homebrew) / latest:SQLSTATE 25P01;主报文 SAVEPOINT can only be used in transaction blocks;错误后状态 IDLE;显式事务修复 INTRANS → IDLE。
10.21 (Debian 10.21-1.pgdg90+1) / pg10:SQLSTATE 25P01;主报文 SAVEPOINT can only be used in transaction blocks;错误后状态 IDLE;显式事务修复 INTRANS → IDLE。
代表案例
运行器从共享语句清单(registry)读取下列无事务保存点和显式块修复语句;完整断言、环境和清理见 案例导出。
-- trigger
SAVEPOINT outside_block;
-- begin
BEGIN;
-- savepoint
SAVEPOINT inside_block;
-- release
RELEASE SAVEPOINT inside_block;
-- commit
COMMIT;
-- verify
SELECT 1;
上述片段的 SQLSTATE、诊断、状态和修复断言来自共享语句清单(registry)(SHA-256 a1ffffc778f82789f1c1ac4027a109fc76e4b315ef2e3a5bdbfc47c8f84ce951);结构化证据。
作者证据 ID:identity, savepoint-path, runtime。选定运行记录:runtime.25P01-batch2-latest-20260909.latest, runtime.25P01-batch2-pg10-20260909.pg10。
版本与边界
SAVEPOINT 案例在 18.6 与 10.21 返回相同主报文的 25P01,显式事务块修复后两个目标均回到 IDLE。
来源
- 上游源码 doc/src/sgml/ref/savepoint.sgml 第 68–78 行
- 上游源码 src/backend/utils/errcodes.txt
- 上游源码 src/backend/access/transam/xact.c 第 3724–3749 行
- 上游源码 src/backend/access/transam/xact.c 第 4418–4424 行
- 核验材料 raw/calls/REL_18_6.jsonl
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
25P01 is no_active_sql_transaction in Class 25.
-
The fixed xact.c paths report 25P01 when SAVEPOINT, RELEASE SAVEPOINT, or ROLLBACK TO SAVEPOINT is issued without an explicit transaction block; the selected SAVEPOINT path is ERROR.
-
The selected SAVEPOINT case returned 25P01 on PostgreSQL 18.6 and 10.21, stayed IDLE in autocommit mode, and completed the explicit-block repair.
-
The fixed xact.c source also uses 25P01 for no-transaction COMMIT/ROLLBACK warnings with "there is no transaction in progress", while COMMIT AND CHAIN and ROLLBACK AND CHAIN use the transaction-block error form.
运行记录
| 目标 | 服务器版本 | 结果 | 覆盖案例 |
|---|---|---|---|
| latest | 18.6 (Homebrew) | passed | savepoint_without_transaction |
| pg10 | 10.21 (Debian 10.21-1.pgdg90+1) | passed | savepoint_without_transaction |
同类 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 |
| 会话在开放事务中空闲超时,被服务器终止。 | 活跃 | |||
| 25P04 | transaction_timeout | ERRCODE_TRANSACTION_TIMEOUT |
ERROR | 17 |
| 事务运行超过 transaction_timeout 被终止。 | 活跃 | |||