SET TRANSACTION
命令设置当前会话的特性。
简介
SET SESSION CHARACTERISTICS
设置一个会话后续事务的默认事务特性。在个体事务中可以用 SET TRANSACTION
覆盖这些默认值。
可用的事务特性是事务隔离级别、事务访问模式(读/写或只读)以及可延迟模式。此外,可以选择一个快照,不过只能用于当前事务而不能作为会话默认值。
一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据:
READ COMMITTED
一个语句只能看到在它开始前提交的行。这是默认值。REPEATABLE READ
当前事务的所有语句只能看到这个事务中执行的第一个查询或者数据修改语句之前提交的行。SERIALIZABLE
当前事务的所有语句只能看到这个事务中执行的第一个查询或者数据修改语句之前提交的行。如果并发的可序列化事务间的读写模式可能导致一种那些事务串行(一次一个)执行时不可能出现的情况,其中之一将会被回滚并且得到一个serialization_failure
错误。
SQL 标准定义了一种额外的级别:READ UNCOMMITTED
。在 PolarDB中READ UNCOMMITTED
被视作 READ COMMITTED
。
一个事务执行了第一个查询或者数据修改语句( SELECT
、 INSERT
、DELETE
、 UPDATE
、FETCH
或 COPY
)之后就无法更改事务隔离级别。
事务的访问模式决定该事务是否为读/写或者只读。读/写是默认值。当一个事务为只读时,如果 SQL 命令INSERT
、UPDATE
、DELETE
和COPY FROM
要写的表不是一个临时表,则它们不被允许。不允许CREATE
、ALTER
以及DROP
命令。不允许COMMENT
、GRANT
、REVOKE
、TRUNCATE
。如果EXPLAIN ANALYZE
和EXECUTE
要执行的命令是上述命令之一,则它们也不被允许。这是一种高层的只读概念,它不能阻止所有对磁盘的写入。
只有事务也是SERIALIZABLE
以及READ ONLY
时,DEFERRABLE
事务属性才会有效。当一个事务的所有这三个属性都被选择时,该事务在第一次获取其快照时可能会阻塞,在那之后它运行时就不会有SERIALIZABLE
事务的开销,并且不会有任何牺牲或者被一次序列化失败取消的风险。这种模式很适合于长时间运行的报表或者备份。
SET TRANSACTION SNAPSHOT
命令允许新的事务使用与一个现有事务相同的快照运行。已经存在的事务必须已经把它的快照用pg_export_snapshot
函数导出。 该函数会返回一个快照标识符,SET TRANSACTION SNAPSHOT
需要被给定一个快照标识符来指定要导入的快照。 在这个命令中该标识符必须被写成一个字符串,例如 '000003A1-1'
。SET TRANSACTION SNAPSHOT
只能在一个事务的开始执行,并且要在该事务的第一个查询或者数据修改语句( SELECT
、 INSERT
、DELETE
、 UPDATE
、FETCH
或 COPY
)之前执行。此外,该事务必须已经被设置为SERIALIZABLE
或者 REPEATABLE READ
隔离级别(否则,该快照将被立刻抛弃, 因为READ COMMITTED
模式会为每一个命令取一个新快照)。 如果导入事务使用了SERIALIZABLE
隔离级别,那么导入快照的事务必须也使用该隔离级别。还有,一个非只读可序列化事务不能导入来自只读事务的快照。
语法
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
之前没有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
等方式设置默认值。
示例
要用一个已经存在的事务的同一快照开始一个新事务,首先要从该现有事务导出快照。这将会返回快照标识符,例如:
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';