PostgreSQL并发控制(二)

在上一文PostgreSQL并发控制(一)中。我们解释了PostgreSQL多版本并发控制MVCC (Multi-version Concurrency Control)是在写数据时创建一个新版本数据,并将新旧版本数据都保存在数据文件中。而并行的其他事务查询数据时,应该选择哪一个版本的数据来呈现呢?本文将进行讲解。

一、事务快照

事务快照是在某个时间点看到的事务状态信息,包括哪些事务已经完成,那些事务还未开始,哪些事务正在进行中。在PostgreSQL中,用txid_current_snapshot()函数来获得当前的事务快照。

postgres=# select txid_current_snapshot();
 txid_current_snapshot
-----------------------
 678:678:
(1 row)

事务快照的文本表现形式:xmin:xmax:xip_list 具体含义如下:

事务快照项解释说明
xminEarliest transaction ID (txid) that is still active. All earlier transactions will either be committed and visible, or rolled back and dead.最早的活跃事务的txid,txid<xmin的事务要么提交,要么回滚
xmaxFirst as-yet-unassigned txid. All txids greater than or equal to this are not yet started as of the time of the snapshot, and thus invisible.第一个尚未分配的txid,txid>=xmin的事务没有开启,所以不可见。
xip_listActive txids at the time of the snapshot. The list includes only those active txids between xmin and xmax; there might be active txids higher than xmax. A txid that is xmin <= txid < xmax and not in this list was already completed at the time of the snapshot, and thus either visible or dead according to its commit status. The list does not include txids of subtransactions.xmin<=txid<xmax中仍然活跃的事务。

 

例1:   100:100:   。     xmin为100,因此txid < 100的事务是非活跃的,要么提交,要么回滚。xmax为100,因此txid ≥ 100的事务尚未开始。

例2:  100:104:100,102  xmin为100,因此txid < 100的事务是非活跃的,要么提交,要么回滚。xmax为104,因此txid ≥ 104的事务尚未开始。xip_list为100,102,所以100,102号事务仍然活跃,101,103号事务不活跃,要么提交、要么回滚。

非活跃事务是回滚还是提交?需要查看PostgreSQL中clog记录,本文不做解释。

 

二、事务快照与事务隔离级别

PostgreSQL中事务隔离级别是通过事务快照来实现的,获取事务快照用来检查元组的可见性。对read committed隔离级别,每执行一条语句都会获得事务快照;对repeatable read,事务只会在执行第一条SQL时获取一次快照。注意,事务快照不是在事务开始时获取,而是在事务中执行语句时获取,看例子:

时间事务一事务二事务三说明
Time_1 begin transaction isolation level repeatable read; 事务二首先开始,并设置为repeatable read,此时事务二并没有获取事务快照。
Time_2begin;  事务一开始,默认read committed隔离级别
Time_3

select count(1) from a;

结果是0条

insert into a values (1 , 'a');

  事务一插入一条记录。
Time_4commit;  事务一提交
Time_5 select count(1) from a; 结果是1条 事务二获取事务快照,此时事务一已经提交,事务一的结果可以查询
Time_6  

begin;

insert into a values (2 , 'b');

commit ;

事务三又插入一条记录,默认read committed隔离级别。
Time_7 select count(1) from a; 结果是1条 事务二仍然使用Time_5获取是事务快照,只看到一条记录。
Time_8 commit; 事务二结束

转载于:https://my.oschina.net/207miner/blog/2994306

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值