oracle事务处理中的版本控制

oracle中有一个典型的问题是银行的转账业务

create table accounts(
account_number number primary key,
account_balance number
);

现在ACCOUNTS表格里的数据如下:
ACCOUNT_NUMBER ACCOUNT_BALANCE
-------------- ---------------
             1             500
             2             250
             3             400
             4             100

通过下面的语句查询帐户总额,
select sum(account_balance) from accounts;

现在假设当已经读取了第1行,准备读取第2行和第3行时,一台自动柜员机(ATM)针对这个表发生了一个事务,将$400.00从账户1转到了账户4,结果怎样?
在几乎所有的其他数据库中,如果想得到“一致”和“正确”的查询答案,就必须在计算总额时对整个表加上共享读锁,但这会大大影响并发性。
通过使用会滚段(Undo段),Oracle则不需要任何锁定,就可以得到正确答案。Oracle是这样做的:


view plaincopy to clipboardprint?<pre class="html" name="code">-------------------------------------------------------------- 
时间   查询                                 转账事务 
-------------------------------------------------------------- 
T1    读第1行;到目前为止sum = $500 
T2                                    更新第1行;对第1行加一个排他锁(也称独占锁, 
                                            exclusive lock),阻止其他更新。第1行现在有$100 
T3    读第2行;到目前为止sum = $750 
T4    读第3行;到目前为止sum = $1150 
T5                                    更新第4行;对第4 行加一个排他锁,阻止其他更新(但不 
                                            阻止读操作)。第4行现在有$500 
T6    读第4行,发现第4行已修改。这会 
      将块回滚到T1时刻的状态。查询从 
      这个块读到值$100 
T7                                    提交事务 
T8    得到答案sum = $1250 
<pre class="html" name="code">--------------------------------------------------------------
时间   查询                                 转账事务


实际上oracle在执行查询的这个事务的过程中它是这样的。

因为这个事务它是查询的事务,所以它允许其他的事务去对这里的数据进行修改,但是如果这个事务本身是对正在访问的数据进行修改的话,那么它将不允许其他的事务对当前事务正在访问的数据进行修改,这个很好理解比如一个人在修改一张卡里面的金额,比如要取出来200,可是如果同时这个事务允许其他的事务同时执行的话,那么比如同时在其他的地方有人又向里面存了300,结果就是在第一个操作者看来取出钱了之后钱反而多了,这从逻辑上是肯定会造成误会的。


那么既然查询的业务它允许修改的进行那么这个事务有事如何保证他们的数据一致性呢?


oracle的版本控制在这个地方就有用了,同一个事务他们所访问的资源的版本是必须一致的,而这个版本就是以事务执行开始时的的时间为标准的,所以就上面的例子来讲,虽然在执行查询期间,卡之间的金额进行的转移,但是因为这个事务它的版本号是一定的,就是查询的起始时间是一定的,那么当oracle去取第4个卡里面的数据的时候它会按照本事务开始执行时所对应的时间去第4张卡里面取数据,因为这张卡的金额修改的事务它跟查询的事务的开始时间是不一样的,而oracle会去检查在那个时间段之后表里面的数据是不是被修改过,如果修改过那么它就会回滚事务到T1时刻,然后查询它的值,这样就保证了数据的一致性了。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值