SET TRANSACTION

SET TRANSACTION命令设置当前会话的特性。

简介

SET SESSION CHARACTERISTICS设置一个会话后续事务的默认事务特性。在个体事务中可以用 SET TRANSACTION覆盖这些默认值。

可用的事务特性是事务隔离级别、事务访问模式(读/写或只读)以及可延迟模式。此外,可以选择一个快照,不过只能用于当前事务而不能作为会话默认值。

一个事务的隔离级别决定当其他事务并行运行时该事务能看见什么数据:

  • READ COMMITTED一个语句只能看到在它开始前提交的行。这是默认值。

  • REPEATABLE READ当前事务的所有语句只能看到这个事务中执行的第一个查询或者数据修改语句之前提交的行。

  • SERIALIZABLE当前事务的所有语句只能看到这个事务中执行的第一个查询或者数据修改语句之前提交的行。如果并发的可序列化事务间的读写模式可能导致一种那些事务串行(一次一个)执行时不可能出现的情况,其中之一将会被回滚并且得到一个 serialization_failure错误。

SQL 标准定义了一种额外的级别:READ UNCOMMITTED。在 PolarDB中READ UNCOMMITTED被视作 READ COMMITTED

一个事务执行了第一个查询或者数据修改语句( SELECTINSERTDELETEUPDATEFETCHCOPY)之后就无法更改事务隔离级别。

事务的访问模式决定该事务是否为读/写或者只读。读/写是默认值。当一个事务为只读时,如果 SQL 命令INSERTUPDATEDELETECOPY FROM要写的表不是一个临时表,则它们不被允许。不允许CREATEALTER以及DROP命令。不允许COMMENTGRANTREVOKETRUNCATE。如果EXPLAIN ANALYZEEXECUTE要执行的命令是上述命令之一,则它们也不被允许。这是一种高层的只读概念,它不能阻止所有对磁盘的写入。

只有事务也是SERIALIZABLE以及READ ONLY时,DEFERRABLE事务属性才会有效。当一个事务的所有这三个属性都被选择时,该事务在第一次获取其快照时可能会阻塞,在那之后它运行时就不会有SERIALIZABLE事务的开销,并且不会有任何牺牲或者被一次序列化失败取消的风险。这种模式很适合于长时间运行的报表或者备份。

SET TRANSACTION SNAPSHOT命令允许新的事务使用与一个现有事务相同的快照运行。已经存在的事务必须已经把它的快照用pg_export_snapshot函数导出。 该函数会返回一个快照标识符,SET TRANSACTION SNAPSHOT需要被给定一个快照标识符来指定要导入的快照。 在这个命令中该标识符必须被写成一个字符串,例如 '000003A1-1'SET TRANSACTION SNAPSHOT只能在一个事务的开始执行,并且要在该事务的第一个查询或者数据修改语句( SELECTINSERTDELETEUPDATEFETCHCOPY)之前执行。此外,该事务必须已经被设置为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';