PHP实战中知识总结 / PgSQL - 事务快照-Transaction Snapshot

一、事务快照

事务快照是一个数据集,用于存储有关单个事务在特定时间点是否所有事务都处于活动状态的信息。在这里,活动事务表示它正在进行或尚未开始。PostgreSQL内部将事务快照的文本表示格式定义为“100:100:”。例如,“100:100:”表示“小于99的TXID为非活性,等于或大于100的TXID为活性”。

可以通过txid_current_snapshot函数显示当前事务的快照。

// active是指transaction in progress or has not yet started
db001=# SELECT txid_current_snapshot();
txid_current_snapshot
----------------------
100:100: // 小于100的txids not active
(1 row) // 大于等于100的txids active
db001=# SELECT txid_current_snapshot();
txid_current_snapshot
----------------------
100:104:100,102
(1 row)
// 格式:xmin:xmax:xip_list
xmin: 最小的active的txid,小于xmin的都是visible的
xmax:第一个还没分配的txid,大于等于xmax的都是invisible的
xip_list:在xmin和xmax之间active的txid

二、事务快照表示的示例:

(1)第一个例子是“100:100:”。

等于或小于99的TXID是不活跃的,因为xmin为100。

等于或大于100的TXID处于活动状态,因为xmax为100。

(2)第二个例子是“100:104:100102”。该快照表示以下内容(图5.8(b)):

等于或小于99的TXID不具有活性。

大于等于104的TXID是活性的。

TXID 100和102具有活性,因为它们存在于xip列表中,而TXID 101和103不具有活性。

三、事务管理器 - transaction manage

事务快照由事务管理器(transaction manager)提供。在读提交隔离级别中,每当执行SQL命令时,事务都会获得快照;否则(可重复读取或可序列化),事务仅在执行第一个SQL命令时获取快照。获取的事务快照用于元组的可见性检查。

使用获取的快照进行可见性检查时,快照中的活动事务必须视为正在进行中,即使它们实际上已提交或中止。此规则很重要,因为它会导致提交读取和可重复读取(或可序列化)之间的行为差异。

四、实例

事务管理器始终保存有关当前正在运行的事务的信息。假设三个事务相继启动,事务_A和事务_B的隔离级别为读已提交,事务_C的隔离级别为可重复读取。

(1)T1:事务_A启动并执行第一个SELECT命令。当执行第一个命令时,事务_A请求此时的txid和快照。在这种情况下,事务管理器分配txid 200,并返回事务快照“200:200:”。

(2)T2::事务_B启动并执行第一个SELECT命令。事务管理器分配txid 201,并返回事务快照“200:200:”,因为事务A(txid 200)正在进行中。因此,无法从事务_B中看到事务_A。

(3)T3:事务_C启动并执行第一个SELECT命令。事务管理器分配txid 202,并返回事务快照“200:200:”,因此,无法从事务_C中看到事务_A和事务_B。

(4)T4:事务_A已提交。事务管理器将删除有关此事务的信息。

(5)T5:事务_B和事务_C执行各自的select命令。B是RC级别会重新获取snapshot=201:201,此时B可以看到A;

事务_C不需要事务快照,因为它处于可重复读取级别,并使用获得的快照,即“200:200:”。因此,事务_A仍然不可见于事务_C。

五、结论

在Read Committed隔离级别,事务在执行每条SQL时都会从事务管理器获取快照,其他隔离级别,事务只会在执行第一条SQL命令时获取一次快照。

PHP实战中知识总结