SET TRANSACTION — 设置当前事务的特性
SET TRANSACTIONtransaction_mode
[, ...] SET TRANSACTION SNAPSHOTsnapshot_id
SET SESSION CHARACTERISTICS AS TRANSACTIONtransaction_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
。在
LightDB中READ
UNCOMMITTED
被视作
READ COMMITTED
。
一个事务执行了第一个查询或者数据修改语句(
SELECT
、
INSERT
、DELETE
、
UPDATE
、FETCH
或
COPY
)之后就无法更改事务隔离级别。
更多有关事务隔离级别和并发控制的信息可见Chapter 14。
事务的访问模式决定该事务是否为读/写或者只读。读/写是默认值。
当一个事务为只读时,如果 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
函数(
见Section 10.27.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。
当前事务的模式可以类似的通过配置参数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
形式除外,这两者是
LightDB扩展。
SERIALIZABLE
是标准中默认的事务隔离级别。在
LightDB中默认值是普通的
READ COMMITTED
,但是你可以按上述的方式更改。
在 SQL 标准中,可以用这些命令设置一个其他的事务特性:诊断区域 的尺寸。这个概念与嵌入式 SQL 有关,并且因此没有在 LightDB服务器中实现。
SQL 标准要求连续的transaction_modes
之间有逗号,
但是出于历史原因
LightDB允许省略逗号。