Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2951399
  • 博文数量: 199
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 4126
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-06 19:06
个人简介

半个PostgreSQL DBA,热衷于数据库相关的技术。我的ppt分享https://pan.baidu.com/s/1eRQsdAa https://github.com/chenhuajun https://chenhuajun.github.io

文章分类

全部博文(199)

文章存档

2020年(5)

2019年(1)

2018年(12)

2017年(23)

2016年(43)

2015年(51)

2014年(27)

2013年(21)

2011年(1)

2010年(4)

2009年(5)

2008年(6)

分类: Mysql/postgreSQL

2013-09-14 01:18:22

PostgreSQL的事务也是基于MVCC实现的。支持3种隔离级别读已提交,可重复读和可串行化。但用户设置读未提交并不会报错而是被映射到读已提交,这是不违反SQL规约的。PostgreSQL的可重复读相当于Oracle的可串行化,即SI。而PostgreSQL的可串行化则是真正的可串行化即Serializable Snapshot Isolation (SSI),这一特性是从9.1开始加进来的。所以,在并发事务隔离的处理上,可以说PostgreSQL走在了包括Oracle,SQL Server在内的商业数据库的前头。下面看看详细测试结果。

1. 测试环境
OS:Windows7
DBMS:PostgreSQL 9.2.4

2. 
测试结果
读已提交:

先执行SQL\后执行SQL
同一行查询 非同行查询 整表查询 同一行插入 非同行插入 同一行更新 非同行更新 整表更新 同一行删除 非同行删除 整表删除
单行查询 OK OK OK 主键冲突 OK OK OK OK OK OK OK
整表查询 OK OK OK 主键冲突 OK OK OK OK OK OK OK
插入

OK(**)

OK

OK(**)

等待(*) OK OK(**) OK OK(**) OK(**) OK OK(**)
单行更新

OK(**)

OK

OK(**)

等待(*) OK 等待(*) OK 等待(*) 等待(*) OK 等待(*)
整表更新

OK(**)

OK

OK(**)

等待(*) OK 等待(*) OK 等待(*) 等待(*) OK 等待(*)
单行删除

OK(**)

OK

OK(**)

等待(*) OK 等待(*) OK 等待(*) 等待(*) OK 等待(*)
整表删除

OK(**)

OK

OK(**)

等待(*) OK 等待(*) OK 等待(*) 等待(*) OK 等待(*)
OK(**):基于更新前的数据,即看到是查询时的快照
等待(*):如果先行的SQL提交,则基于更新后的数据,否则基于原来的数据
注:黄色代表和Oracle的读已提交不同的地方


可重复读/可串行化

先执行SQL\后执行SQL
同一行查询 非同行查询 整表查询 同一行插入 非同行插入 同一行更新 非同行更新 整表更新 同一行删除 非同行删除 整表删除
单行查询 OK OK OK 主键冲突 OK OK OK OK OK OK OK
整表查询 OK OK OK 主键冲突 OK OK OK OK OK OK OK
插入

OK(***)

OK

OK(***)

等待(*) OK OK(***) OK OK(***) OK(***) OK OK(***)
单行更新

OK(***)  

OK

OK(***)

等待(*) OK 等待(**) OK 等待(**) 等待(**) OK 等待(**)
整表更新

OK(***)

OK

OK(***)

等待(*) OK 等待(**) OK 等待(**) 等待(**) OK 等待(**)
单行删除

OK(***)

OK

OK(***)

等待(*) OK 等待(**) OK 等待(**) 等待(**) OK 等待(**)
整表删除

OK(***)

OK

OK(***)

等待(*) OK 等待(**) OK 等待(**) 等待(**) OK 等待(**)
OK(***):基于更新前的数据,查询看到的是事务开始时的快照
等待(*):
如果先行的SQL提交,则基于更新后的数据,否则基于原来的数据
等待(**):如果先行的SQL提交,则报更新冲突的错误
注:黄色代表和读已提交不同的地方

3. PostgreSQL串行化(SSI)和可重复读(SI)的区别
PostgreSQL串行化(SSI)级别下,比可重复读(SI)多了是否能串行化的检查,如果在某个时点(SQL语句执行或提交时),发现串行化冲突,则终止事务并报错。还是用之前的例子来说明。
SSI下,2个事务按下面的顺序交替执行,在下面的第6步,PostgreSQL检出串行化冲突,因而报错并取消事务2。这样先提交的事务1就不违反可串行化原则。
1) 事务1:select * from tb1;
2) 事务2:select * from tb1;
3) 事务1:insert into tb1 values(5,'a');
4) 事务2:insert into tb1 values(6,'a');
5) 事务1:commit;
6) 事务2:commit;//报错

可重复读(SI)时,上面的6)是能执行成功的。

*)上面的6)如果执行成功就不符合真正的串行化。假设2个事务按照 事务1->事务2 的顺序串行执行, 在2)中事务2应该能看到3)事务1插入的数据,这是不可能的;反之 事务2->事务1 亦然。


*)详细测试方法请参考:
并发事务下各数据库外部表现实测之一(SQL Server篇)
http://blog.chinaunix.net/uid-20726500-id-3883105.html
阅读(3003) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

kafkaaka2016-12-16 09:32:55

so good!上次咨询你的问题,谢谢你的解答、确实是他们设置的是可重复读导致的。   我去官网看了可重复读和读已提交区别。 但是不是很懂可串行化与可重复读的区别,你最下面这个例子讲的太棒咯。 以后就常驻你的blog了。哈哈