Oracle 并发与一致性

      在多用户下,并发与一致性显得十分重要,现在通过实例来加以分析。并发操作,我们知道可能造成数据的不一致性,怎么来解决呢?很多地方都会遇到这种情况,可以采取加锁的方式来避免。从模式上来分,可以分为共享锁和排它锁,从字面上可以很好的理解它们的意思;从粒度上讲,可以分为表级锁和行级锁,表级锁就是锁定整个表(如比不同删除表或者修改表的结构);行级锁就是作用在某些行上,如果修改了某一行,就在这个行上加行级排它锁,其它的就不能访问这个行了。当然具体有锁的不同模式,如行级排它锁等,我想没有必要去讲得这么细,现在只需要知道有这些基本的概念在这里就行了。


      提到并发与一致性,又不得提到事务,事务有不同的隔离级别,对应解决脏读(读到了别人没有提交的事务)、不可重复读(两次读操作得到的结果不同)、幻读(有人添加了数据)情况。每个事务都有一个事务ID,事务存在数据块的事务槽中,它有不同的状态。


      讲到了事务,不得不说undo和redo,undo是保存数据修改之前的信息;而redo是重复这个操作。具体它们的结构还得单独去深入研究,在这里仅仅给出它们的基本功能。


      假设我们设定的隔离级别为Read Committed.现在来分析两个会话对一张表的操作,看看具体的结果是怎样的?
有一张表:Person
Name Age
aaa  20
bbb  30


      一个会话A做:delete from Person where Name like 'aaa';(现在没有commit)
     此时在aaa这一行加上了行级排它锁,但是没有commit,此时生成了redo 和 undo的信息。
     另一个会话B做:select * from Person;
     它的结果是:Name Age 
                       aaa  20
                       bbb  30

     B在查询时,发现这一行有行级排它锁,再看看它的事务提交没,如果没有提交,就从undo中找到它被修改之前的值,所以返回上面的结果信息。
     总结一下流程:
     1)找到对应数据块的信息,发现这一行被锁定,再找到对应的事务ID;
     2)发现事务是没有提交的,根据这个事务ID到undo块中去找之前的信息(undo中也存有事务的ID信息);
     3)将没有标记锁定的行读出来和undo修改之前的信息读出来。


     现在又有一个问题来了,不是说只能读到已提交的数据吗?ok,我们再来看一个问题。
     会话A:读一个表的数据,假设读的过程很长;
     会话B:在会话A中,删除了该表的某一行,commit了;
     现在会话A会发现这个删除的行吗?即是少读了一行。


     这里又不得不说一个概念就是SCN,这个是只会增加不会减少的数字标志。读的过程相当于一个快照,假设这个时刻有1000行,而在读的过程中删除了一行,其实A是不会发现的,这是因为在上一刻的时间点(快照)就是1000行,所以不会读到999行。这是怎么来实现的呢。就是依靠这个SCN。
SCN按照时间来生产的,在某个时刻,它的编号是100,如果过一会儿,又有事务在数据块中修改数据,此时的SCN变成了102,那么SCN为100的事务发现有比自己大的SCN存在,就说明有人修改了数据,所以必需从undo中找出之前的数据,所以才会返回1000行数据。


     今天只是从宏观上说说oracle 数据的并行和一致性,里面有很多细的东西深入我们去学习,后面我也会写一系列的文章来分享我的学习体会。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30024515/viewspace-1434671/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/30024515/viewspace-1434671/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值