本文引用:
http://www.interdb.jp/pg/pgsql05.html
《PostgreSQL指南》第5章
事务快照是一个数据集,存储着某个特定事务在某个特定时间点所看到的事务状态信息,哪些事务处于活跃状态。
1.PG中实现的事务隔离级别
隔离等级 | 脏读 | 不可重复读 | 幻读 | 串行化异常 |
---|---|---|---|---|
READ COMMITTED | 不可能 | 可能 | 可能 | 可能 |
REPEATABLE READ | 不可能 | 不可能 | 不可能 | 可能 |
SERIALIZABLED | 不可能 | 不可能 | 不可能 | 不可能 |
2.PG中事务快照的文本形式
xmin:xmax:xip_list
100:104:100,102
xmin 最早仍然活跃的事务的txid
xmax 第一个尚未分配的txid(例如只开启一个begin)
xip_list 获取快照时活跃事务的txid列表
3.PG事务快照及可见性示例
Transaction manager保存着当前运行的事务有关信息
Transaction_A和Transaction_B的隔离级别为Read Committed,Transaction_C的隔离级别为Repeatable Read
T1:Transaction_A启动并执行第一条select,此时请求txid和Snapshot,Transaction manager分配txid=200,Snapshot=200:200:
T2:Transaction_B启动并执行第一条select,此时请求txid和Snapshot,Transaction manager分配txid=201,Snapshot=200:200:
因为Transaction_A(txid=200)正在进行中,Transaction_B(txid=201)无法看到Transaction_A(txid=200)
T3:Transaction_C启动并执行第一条select,此时请求txid和Snapshot,Transaction manager分配txid=202,Snapshot=200:200:
Transaction_C(txid=202)无法看到Transaction_A(txid=200)和Transaction_B(txid=201)
T4:Transaction_A提交
T5:Transaction_B和Transaction_C各自执行第二条select,
此时Transaction_B需要一个新的事务快照,因为它使用了Read Committed隔离级别,获取的新事务快照为201:201:所以Transaction_A对Transaction_B可见
此时Transaction_C不需要新的事务快照,因为它处于Repeatable Read隔离级别,继续使用旧的事务快照为200:200:所以Transaction_A对Transaction_C不可见
注:在Read Committed隔离级别,事务在执行每条SQL时都会从事务管理器获取快照,其他隔离级别,事务只会在执行第一条SQL命令时获取一次快照。