Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

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 命令:INSERTUPDATEDELETEMERGECOPY FROM(前提是其写入的表不是一个临时表);所有 CREATEALTERDROP 命令;COMMENTGRANTREVOKETRUNCATE;以及 EXPLAIN ANALYZEEXECUTE(前提是其执行的命令在所列命令中)。这是一个高层次的只读概念,它并不能阻止所有写入磁盘的操作。

除非事务也是 SERIALIZABLEREAD ONLY,否则 DEFERRABLE 事务属性不会产生任何效果。当为某个事务选择所有三个属性时,事务在第一次获取其快照时可能会阻塞,然后它能够在没有 SERIALIZABLE 事务的正常开销的情况下运行,并且不会产生或被串行化失败取消的任何风险。此模式非常适合长时间运行的报告或备份。

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

备注

如果在之前的 START TRANSACTIONBEGIN 中未执行 SET TRANSACTION,那么它会发出一个警告,并不会产生其他影响。

可以通过在 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 允许省略逗号。