SET TRANSACTION
Name
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
。
事务隔离级别在事务中第一个查询或数据修改语句(SELECT
, INSERT
, DELETE
, UPDATE
, FETCH
, 或 COPY
)执行之后就不能再次设置。 参阅Chapter 13 获取有关事务隔离级别和并发性控制的更多信息。
事务访问模式决定事务是读/写还是只读。读/写是缺省。如果一个事务是只读, 而且写入的表不是临时表,那么下面的 SQL 命令是不允许的:INSERT
, UPDATE
, DELETE
, COPY FROM
; 而所有的CREATE
, ALTER
, DROP
; COMMENT
, GRANT
, REVOKE
, TRUNCATE
; EXPLAIN ANALYZE
, EXECUTE
都不允许。这是一个高层次的只读概念, 它并不阻止所有对磁盘的写入。
DEFERRABLE
事务属性没什么影响,除非事务也是SERIALIZABLE
和READ ONLY
。当为一个事务选择所有这三个属性时, 事务可能会在第一次请求它的快照时堵塞,之后运行时可以不需要正常的SERIALIZABLE
事务的开销并且不会有任何导致序列化失败或被取消的风险。 这个模式很适合于长时间运行的报告或备份。
SET TRANSACTION SNAPSHOT
命令允许一个新的事务运行的快照 与一个现存事务的相同。该已有的事务必须已经用pg_export_snapshot
函数 (参阅Section 9.26.5)输出了它的快照。 这个函数返回一个快照标识符,这个标识符必须给SET TRANSACTION SNAPSHOT
以指出要输出哪个快照。该标识符在这个命令中必须写作字符串,例如'000003A1-1'
。 SET TRANSACTION SNAPSHOT
只能在该事务第一次查询或数据修改语句执行之前设置, (SELECT
, INSERT
, DELETE
, UPDATE
, 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
或在配置文件里等方法设置。参考Chapter 18获取更多信息。
例子
开启一个与已经存在的事务具有相同快照的新事务,首先从现存事务中输出快照。 这将返回快照的标识符,例如:
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT pg_export_snapshot();
pg_export_snapshot
--------------------
000003A1-1
(1 row)
然后在新打开的事务的开始的SET TRANSACTION SNAPSHOT
命令中给出快照标识符:
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION SNAPSHOT '000003A1-1';
兼容性
这些命令在SQL标准中定义了,除了DEFERRABLE
事务模式和SET TRANSACTION SNAPSHOT
格式是PostgreSQL 的扩展。
标准里的缺省事务隔离级别是SERIALIZABLE
; 但在PostgreSQL里,缺省隔离级别是 READ COMMITTED
, 但是你可以用上面描述的方法修改它。
在 SQL 标准里还有另外一种事务特性可以用这些命令设置:诊断范围的大小。 这个概念只用于嵌入式 SQL ,因此没有在PostgreSQL服务器里实现。
SQL 标准要求在相连的_transaction_modes_
之间使用逗号,但是因为历史原因,PostgreSQL允许省略这个逗号。