Skip to content

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命令允许新事务使用与现有事务相同的快照运行。预先存在的交易必须使用pg_export_snapshot函数导出其快照(请参阅第 9.27.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等设置默认值。有关更多信息,请参阅第 20 章

当前事务的模式同样可以通过配置参数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允许省略逗号。