`
flyfoxs
  • 浏览: 294771 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

白话2种Oracle的事务隔离

阅读更多

Oracle事务的隔离级别有2总, Read Commitment, Serializable, Read Only (另外还有2种事务隔离级别,Read Uncommitted, Repatable Read,Oracle没有单独提供.)

 

Read Only, 看名字就比较简单,在此我们不做讨论,下面主要分析一下Read Commitment, Serializable. 

 

一句话描述:

Read Commitment: 读取在语句开始时已经提交的, 修改冲突通过写一致性来解决数据的一致性.

Serializable:            读取在事务开始时已经提交的. 修改冲突确保先提交的成功,后修改的回滚.

 

比较细节

 

不同点 

  读一致性 写冲突
Read Commitment 如果事务进行过程中,有数据在别的事务里面提交了,可以立即被当前事务读取到. 先修改的可以正常提交,后修改的必须等到先修改提交之后.然后通过写一致性来重启事务
Serializable:  事务开始后,其他事务的所有修改对当前事务没有任何影响 后修改数据的事务同样会被阻塞,但是当阻塞解除提交时会出现ORA-08177异常.
(ORA-08177: can't serialize access for this transaction)

 

 

 

相同点

 
  读一致性 写冲突
Read Commitment 只有提交后的数据才会被读取,都不会读取脏数据. 后修改数据的事务都会被阻塞,无法提交.
Serializable: 
 
 实验过程
下面的2个实验,比较了Oracle所支持的事务隔离模式, 在读取和修改数据时的详细区别. 如何切换数据库的隔离模式,可以参考下面的语句.
ALTER SESSION SET ISOLATION_LEVEL = READ COMMITTED;
ALTER SESSION SET ISOLATION_LEVEL = serializable;
 
  •  数据初始化
 下面的2个实验,在开始前需要使用上面的初始化脚本Reset数据.
DROP TABLE XXRPTH.TEST;

CREATE TABLE XXRPTH.TEST
(
  NAME   VARCHAR(10),
  VALUE  NUMBER(22)
);

insert into test values('lilao_1', 1);
insert into test values('lilao_2', 2);
insert into test values('lilao_3', 3);

commit;
 
  • 实验#1: 读取变化数据的区别
关键比较点,已经标红高亮
时间 事务1 事务2 Read Commitment Serializable: 
t1 savepoint aaa;    显示开启事务1  
t2   savepoint bbb;     显示开启事务2
t3   update test 
set value=value+10 ;
   
t4 select count(*) from test
where value>10;
  结果是0(读可提交) 结果是0
t5   commit;    
t6 select count(*) from test
where value>10;
  结果是3(幻象读,和t4时间读取的记录条数不一样了) 结果是0
t7 commit;      
t8 select * from test;   NAME            VALUE
---------- ----------
lilao_1            11
lilao_2            12
lilao_3            13
NAME            VALUE
---------- ----------
lilao_1            11
lilao_2            12
lilao_3            13
  
 
 
  • 实验#2: 写冲突的区别 
关键比较点,已经标红高亮
时间 事务1 事务2 Read Commitment Serializable: 
t1 savepoint aaa;    显示开启事务1  
t2   savepoint bbb;    显示开启事务2
t3   update test 
set value=value+10 ;
   
t4 select count(*) from test
 where value>10;
  结果是0(读可提交) 结果是0
t5 update test 
set value=value+100;
     
t6   commit;   事务2提交时,事务1会抛出异常
ORA-08177: can't serialize access for this transaction
t7 select * from test;   NAME            VALUE
---------- ----------
lilao_1           111
lilao_2           112
lilao_3           113
NAME            VALUE
---------- ----------
lilao_1             1
lilao_2             2
lilao_3             3
t8 commit;     虽然事务1在T6时,抛出异常,但是事务并未终止.
所以T7时间没有查询到事务2的修改
t9 select * from test;   NAME            VALUE
---------- ----------
lilao_1           111
lilao_2           112
lilao_3           113
NAME            VALUE
---------- ----------
lilao_1            11
lilao_2            12
lilao_3            13
 
 
1
0
分享到:
评论
2 楼 flyfoxs 2014-07-17  
cwqcwqmax9 写道
感觉 楼主测试  Serializable   的结果 和我 预想的不同,按照道理  设置完Serializable 后 ,第二个事物读取 和  写入应该在第一个事物完成 后再执行


谢谢你反馈.你说的有道理,如果第一个事务先写数据是好理解些.

但是安装上面的测试步骤下来,测试结果就会像上面写的,我都是严格测试了的.

如果的确有不对的,你可以指出来,哪个结果不对,我再看看.
1 楼 cwqcwqmax9 2014-07-17  
感觉 楼主测试  Serializable   的结果 和我 预想的不同,按照道理  设置完Serializable 后 ,第二个事物读取 和  写入应该在第一个事物完成 后再执行

相关推荐

Global site tag (gtag.js) - Google Analytics