2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

SET TRANSACTION

SET TRANSACTION — 设置当前事务的特性

概要

SET TRANSACTION transaction_mode [, ...]
SET TRANSACTION SNAPSHOT snapshot_id
SET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...]

where transaction_mode is one of:

    ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
    READ WRITE | READ ONLY
    [ NOT ] DEFERRABLE

描述

SET TRANSACTION 命令用于设置当前事务的特性。它对任何后续事务都无效。SET SESSION CHARACTERISTICS 用于设置会话后续事务的默认事务特性。这些默认值可以被 SET TRANSACTION 为单个事务覆盖。

可用的事务特性是事务隔离级别、事务访问模式(读/写或只读)以及延迟模式。此外,可以选择一个快照,但仅限于当前事务,不能作为会话默认值。

事务的隔离级别决定了在其他事务并发运行时,该事务可以看到什么数据

READ COMMITTED

语句只能看到在语句开始之前已提交的行。这是默认值。

REPEATABLE READ

当前事务的所有语句只能看到在当前事务中第一个查询或数据修改语句执行之前已提交的行。

SERIALIZABLE

当前事务的所有语句只能看到在当前事务中第一个查询或数据修改语句执行之前已提交的行。如果并发的可串行化事务之间的读写模式会造成一种情况,而这种情况在任何串行(一次一个)执行这些事务的情况下都不可能发生,那么其中一个事务将被回滚并出现 serialization_failure 错误。

SQL 标准定义了一个额外的级别 READ UNCOMMITTED。在 PostgreSQL 中,READ UNCOMMITTED 被视为 READ COMMITTED

事务的隔离级别在事务中的第一个查询或数据修改语句(SELECTINSERTDELETEUPDATEMERGEFETCHCOPY)执行后就不能再更改了。有关事务隔离和并发控制的更多信息,请参阅 第 13 章

事务的访问模式决定了事务是读/写还是只读。读/写是默认模式。当事务为只读时,以下 SQL 命令是不允许的:INSERTUPDATEDELETEMERGE,以及 COPY FROM(如果它们会写入的表不是临时表);所有 CREATEALTERDROP 命令;COMMENTGRANTREVOKETRUNCATE;以及 EXPLAIN ANALYZEEXECUTE(如果它们要执行的命令属于上述列表中的命令)。这是一个高级别的只读概念,并不阻止所有写入磁盘的操作。

DEFERRABLE 事务属性只有在事务同时也是 SERIALIZABLEREAD ONLY 时才有效。当这三个属性都为事务选择时,事务在首次获取其快照时可能会被阻塞,之后它就可以在没有 SERIALIZABLE 事务的正常开销的情况下运行,并且没有任何风险会导致或被序列化失败取消。这种模式非常适合长时间运行的报告或备份。

SET TRANSACTION SNAPSHOT 命令允许新事务使用与现有事务相同的 快照 运行。预先存在的事务必须已使用 pg_export_snapshot 函数导出了其快照(请参阅 第 9.28.5 节)。该函数返回一个快照标识符,必须将其提供给 SET TRANSACTION SNAPSHOT 来指定要导入的快照。在此命令中,标识符必须写成字符串字面量,例如 '00000003-0000001B-1'SET TRANSACTION SNAPSHOT 只能在事务开始时执行,即在事务的第一个查询或数据修改语句(SELECTINSERTDELETEUPDATEMERGEFETCHCOPY)之前执行。此外,事务必须已经设置为 SERIALIZABLEREPEATABLE READ 隔离级别(否则,快照将立即被丢弃,因为 READ COMMITTED 模式为每个命令获取新快照)。如果导入事务使用 SERIALIZABLE 隔离级别,那么导出快照的事务也必须使用该隔离级别。此外,非只读的可串行化事务不能从只读事务导入快照。

注释

如果 SET TRANSACTION 在没有先执行 START TRANSACTIONBEGIN 的情况下执行,它会发出警告,否则不会有任何效果。

可以通过在 BEGINSTART TRANSACTION 中指定所需的 transaction_modes 来省略 SET TRANSACTION。但是,SET TRANSACTION SNAPSHOT 没有这个选项。

会话默认事务模式也可以通过配置参数 default_transaction_isolationdefault_transaction_read_onlydefault_transaction_deferrable 来设置或查看。(实际上 SET SESSION CHARACTERISTICS 只是设置这些变量的冗长等价形式,使用 SET 命令。)这意味着默认值可以在配置文件中设置,通过 ALTER DATABASE 等方式设置。有关更多信息,请参阅 第 19 章

当前事务的模式也可以通过配置参数 transaction_isolationtransaction_read_onlytransaction_deferrable 来设置或查看。设置其中一个参数的作用与相应的 SET TRANSACTION 选项相同,并且具有相同的限制条件。但是,这些参数不能在配置文件中设置,也不能从任何除了实时 SQL 之外的来源设置。

示例

要以与现有事务相同的快照开始一个新事务,请首先从现有事务中导出快照。这将返回快照标识符,例如

BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT pg_export_snapshot();
 pg_export_snapshot
---------------------
 00000003-0000001B-1
(1 row)

然后在新打开的事务开始时,在 SET TRANSACTION SNAPSHOT 命令中提供快照标识符

BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION SNAPSHOT '00000003-0000001B-1';

兼容性

这些命令定义在SQL标准中,除了 DEFERRABLE 事务模式和 SET TRANSACTION SNAPSHOT 形式,这些是 PostgreSQL 的扩展。

在标准中,SERIALIZABLE 是默认的事务隔离级别。在 PostgreSQL 中,默认值通常是 READ COMMITTED,但您可以按上述方式更改它。

在 SQL 标准中,还有一个事务特性可以通过这些命令设置:诊断区域的大小。这个概念特定于嵌入式 SQL,因此在 PostgreSQL 服务器中没有实现。

SQL 标准要求在连续的 transaction_modes 之间使用逗号分隔,但出于历史原因,PostgreSQL 允许省略逗号。

提交更正

如果您在文档中看到任何不正确、不符合您对特定功能的使用体验或需要进一步澄清的内容,请使用 此表格 报告文档问题。