Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2945181
  • 博文数量: 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)

分类: Oracle

2013-09-14 00:30:56

Oracle采用MVCC技术进行事务隔离,它只支持2种隔离级别,读已提交和可串行化,设置其他隔离级别会报错。这种基于MVCC的可串行化也被称为SNAPSHOT ISOLATION(SI)。就像SNAPSHOT的字面意思一样,MVCC像是给每个事务保留一个快照,对于数据的读取可以不受其他事务的影响。读已提交和可串行化的区别在于SNAPSHOT采取的时点,前者在SQL执行时,后者在事务开始时。下面参照之前的做法也对Oracle事务进行实测。

1. 测试环境
OS:RHEL6
DBMS:Oracle 11g

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提交,则基于更新后的数据,否则基于原来的数据
注:黄色代表和SQL Server 的READ_COMMITTED_SNAPSHOT=ON时的读已提交不同的地方

从上面的表可以看出,Oracle 的读已提交比SQL Server的READ_COMMITTED_SNAPSHOT=ON时的读已提交基本上差不多,但处理插入时阻塞的可能性更小。

可串行化

先执行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提交,则报更新冲突的错误,"ORA-08177: 无法连续访问此事务处理" 
注:黄色代表和读已提交不同的地方

3.  Oracle的串行化(SI)和真正串行化的区别
Oracle的串行化(SI)其实等同于SQL Server的SNAPSHOT,它满足SQL标准对可串行化的要求,但并不是真正的可串性化。下面用一个例子来说明

SI下,2个事务按下面的顺序交替执行,可以执行成功。
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;

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

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