oracle数据库:开发成功的Oracle应用_笔记9
1.3.3多版本控制(续)
2读一致性和非阻塞读
create table accounts
(account_number number primary key,
account_balance number
);
行 账号 账户余额(美元)
1 123 500.00
2 234 250.00
3 345 400.00
4 456 100.00
select sum(account_balance) from accounts;
这个例子的答案很明显:$1250。
不过,如果现在读了第1行,准备读第2行和第3行时,一台自动柜员机(ATM)针对这个表发生了一个事务,将$400从账户123转到了账户456,又会怎么样呢?查询会计算出第4行的余额为$500,最后就得到了$1650,是这样吗?当然,应该避免这种情况,因为这是不对的,任何时刻账户余额列中的实际总额都不是这个数。读一致性就是Oracle为避免发生这种情况所采用的办法。
Oracle会利用多版本控制来得到结果,也就是查询开始时那个时间点的结果,然后完成查询,而不做任何锁定。
那么,Oracle如何在读取时既得到正确一致的答案又不锁定任何数据呢?也就是刘,如何做到不降低并发性?秘密就在于Oracle使用的事务机制。只要你修改数据,Oracle就会在两个不同位置创建记录条目。一个条目放在重做日志中,Oracle会在这里存储足够的信息来重做或“前滚”事务。对于插入,这个条目就是插入的行。对于删除,则是一个消息(要删除文件X,块Y,行槽Z中的行)。诸如此类。另一个条目就是撤销条目,写至一个undo段。如果事务失败,需要撤销,Oracle将从undo段中读取“前映像”并恢复数据。除了使用这个undo段数据撤销事务外,Oracle还会用它撤销读数据块时对块作出的改变,也就是说会把块恢复到查询开始时的状态。这样一来,你就能够通过一个锁正确地读取数据,不仅可以得到正确一致的答案,也不会锁定任何数据。
所以,对这个例子来说,Oracle得到的答案
时间 查询 转账事务
T1 读第1行;到目前为止balance=$500、sum=$500
T2 更新第1行。对第1行加一个排他锁,阻止其他更新。第1行现在有$100
T3 读第2行;到目前为止balance=$250、sum=$750
T4 读第3行;到目前为止balance=$400、sum=$1150
T5 更新第4行。对第4行加一个排他锁,阻止其他更新(但不阻止读操作)。第4行现在有$500
T6 读第4行,发现第4行已修改。这会将块回滚到T1时刻的状态。查询从这个块读到值$100
T7 提交事务
T8 得到答案$1250
在T6时,Oracle有效地“摆脱”了事务加在第4行上的锁。非阻塞读是这样实现的:Oracle只看数据是否改变,它并不关心数据当前是否锁定(锁定意味着数据已经改变)。Oracle只是从回滚段中取回原来的值,并继续处理下一个数据块。
http://www.52ij.com/jishu/5137.htmloracle数据库:开发成功的Oracle应用_笔记8
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5138.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
