SET TRANSACTION — 设置当前事务的特性
SET TRANSACTIONtransaction_mode
[, ...] SET TRANSACTION SNAPSHOTsnapshot_id
SET SESSION CHARACTERISTICS AS TRANSACTIONtransaction_mode
[, ...] wheretransaction_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
。
在事务的第一个查询或数据修改语句(SELECT
、INSERT
、DELETE
、UPDATE
、MERGE
、FETCH
或 COPY
)执行后,不能更改事务隔离级别。有关事务隔离和并发控制的更多信息,请参见 第 13 章。
事务访问模式确定事务是读/写还是只读。读/写是默认值。当事务是只读时,以下 SQL 命令是不允许的:INSERT
、UPDATE
、DELETE
、MERGE
和 COPY FROM
(如果它们要写入的表不是临时表);所有 CREATE
、ALTER
和 DROP
命令;COMMENT
、GRANT
、REVOKE
、TRUNCATE
;以及 EXPLAIN ANALYZE
和 EXECUTE
(如果它们要执行的命令在列出的命令中)。这是一个高级别的只读概念,它不会阻止所有写入磁盘的操作。
DEFERRABLE
事务属性只有在事务也是 SERIALIZABLE
和 READ ONLY
时才有效。当为事务选择所有这三个属性时,事务在首次获取其快照时可能会被阻止,之后它可以在没有 SERIALIZABLE
事务的正常开销且没有任何导致序列化失败或被取消的风险的情况下运行。此模式非常适合长时间运行的报告或备份。
SET TRANSACTION SNAPSHOT
命令允许新事务使用与现有事务相同的快照运行。预先存在的事务必须使用 pg_export_snapshot
函数导出其快照(请参见第 9.28.5 节)。该函数返回一个快照标识符,必须将其提供给 SET TRANSACTION SNAPSHOT
以指定要导入的快照。标识符必须在此命令中写为字符串文字,例如 '00000003-0000001B-1'
。SET TRANSACTION SNAPSHOT
只能在事务开始时执行,在事务的第一个查询或数据修改语句(SELECT
、INSERT
、DELETE
、UPDATE
、MERGE
、FETCH
或 COPY
)之前。此外,该事务必须已设置为 SERIALIZABLE
或 REPEATABLE READ
隔离级别(否则,快照将被立即丢弃,因为 READ COMMITTED
模式为每个命令采用新的快照)。如果导入事务使用 SERIALIZABLE
隔离级别,则导出快照的事务也必须使用该隔离级别。此外,非只读的可序列化事务不能从只读事务导入快照。
如果执行 SET TRANSACTION
时没有事先执行 START TRANSACTION
或 BEGIN
,则它会发出警告,否则没有任何效果。
可以通过在 BEGIN
或 START TRANSACTION
中指定所需的transaction_modes
来省略 SET TRANSACTION
。但是,该选项不适用于 SET TRANSACTION SNAPSHOT
。
会话默认事务模式也可以通过配置参数 default_transaction_isolation、default_transaction_read_only 和 default_transaction_deferrable 设置或检查。(事实上,SET SESSION CHARACTERISTICS
只是使用 SET
设置这些变量的详细等效方法。)这意味着可以在配置文件中,通过 ALTER DATABASE
等设置默认值。有关更多信息,请查阅第 19 章。
当前事务的模式也可以通过配置参数 transaction_isolation、transaction_read_only 和 transaction_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 允许省略逗号。
如果您发现文档中任何不正确、与您使用特定功能的经验不符或需要进一步澄清的内容,请使用此表单报告文档问题。