受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

SET TRANSACTION

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

Synopsis

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

其中 transaction_mode 是下列之一:

    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

在事务执行第一条查询或数据修改语句(SELECTINSERTDELETEUPDATEMERGEFETCH,或 COPY)之后,事务隔离级别就不能再更改。有关事务隔离和并发控制的更多信息,请参见 Chapter 13

事务访问模式决定事务是读/写还是只读。读/写是默认值。当事务为只读时, 下列 SQL 命令会被禁止:INSERTUPDATEDELETEMERGE 以及 COPY FROM,前提是它们要写入的表不是临时表; 所有 CREATEALTERDROP 命令;COMMENTGRANTREVOKETRUNCATE;以及 EXPLAIN ANALYZEEXECUTE,前提是它们要执行的命令属于上述列表。 这是一个较高层面的只读概念,并不会阻止所有写入磁盘的行为。

只有当事务同时是SERIALIZABLEREAD ONLY时,DEFERRABLE 事务属性才会生效。当为一个事务同时选择这三个属性时,该事务在 首次获取其快照时可能会阻塞;在此之后,它便可以运行,而无需承担普通 SERIALIZABLE事务的常规开销,也不会有促成 序列化失败或因序列化失败而被取消的风险。这种模式非常适合长时间运行的 报表或备份。

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

注解

如果执行SET TRANSACTION之前没有 START TRANSACTION或者 BEGIN,它会发出一条警告,除此之外没有任何效果。

可以不使用SET TRANSACTION,而是在 BEGINSTART TRANSACTION中指定所需的 transaction_modes。但是, 对于SET TRANSACTION SNAPSHOT,这种方式不可用。

会话默认的事务模式也可以通过配置参数 default_transaction_isolationdefault_transaction_read_onlydefault_transaction_deferrable来设置或检查(实际上, SET SESSION CHARACTERISTICS只是用 SET设置这些变量的一种更冗长的等价写法)。这意味着可以通过配置文件、 ALTER DATABASE等方式设置默认值。详见 Chapter 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允许省略逗号。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。