|
最初由 guorui 发布
[B]各位老大过年好!
hannibal 论述“oracle读出的数据当前可能是不正确的”的论据是“oracle可以利用SCN找到最早的数据(注意这不是当前的数据)”。这个论据是错误的,我的依据如下:
“Whenever a transaction is committed, LGWR writes the transaction redo records from the redo log buffer of the SGA to a redo log file, and assigns a system change number (SCN) to identify the redo records for each committed transaction.”(摘自Oracle联机文档 http://download-west.oracle.com/ ... 4231/onlineredo.htm)。无论多么小的事务,每次提交commit产生一个新SCN号。
“When the Oracle server begins executing a SELECT statement, it determines the current system change number (SCN) and ensures that any changes not committed before this SCN are not processed by the statement.”(摘自Oracle DBA教材) 。注意是“current”SCN ,不是hannibal 认为的“最早的”SCN。
假设多个查询发起时SCN不一样(不同时开始),而且多个查询发起之间出现了相关数据提交,即便多个查询同时结束,查询的结果也会不同,即,查询结果有多个版本。每个查询都查到自己发起那一时刻的一致性数据(每个查询发起时的数据快照),结果中没有未提交的数据,即,没有不一致数据。这就是Oracle“多版本读一致性”。所以,我的结论是Oracle读的是正确的数据。
“oracle可以看到别人正在修改而没有提交“之前”的数据。”意思正确,但是容易引起歧义,因为“之前”可以理解为“修改之前”和“提交之前”,“提交之前”的理解显然错了。建议表述为“Oracle可以看到别人‘正在修改而没有提交’的数据的原始值。”
cliser 的例子中,“朋友正在存”,还没有提交,显而易见,储户本来就不应该看到朋友的未提交存款,所以,Oracle提供的不是“虚假的信息”,是可以对账的正确信息,所以,cliser的“储户就获得了虚假的信息”的结论是错误的。
假设这时候储户看到了朋友的存款,但是朋友又取消了存款,这种情况下储户看到的信息才是虚假信息。Oracle默认设置下是不会读到虚假信息的,而DB2在允许读取未提交信息的状态下会读出虚假信息(脏读,UR)。顺便说一句,Oracle通过设置一些少用的参数,也可以实现DB2的功能,例如UR,当然UR不是什么好功能。
A用户修改数据但是没提交,B用户可以读修改前的数据,这是很多并发系统具有的特征。例1,你用PowerPoint打开一个文档正在修改没有关闭,当你再到资源管理器中打开一次时,PowerPoint就提示你以只读方式打开未修改的版本;例2,当你从文档管理软件(例如VisualSafe)中Check Out一个文档来修改,在你Check In之前,其他人只能只读这个文档的原始版本。
有一致的数据,就应该能被读出来,这是数据库应有的功能。如果不能被读出来,有什么好处呢?难道就是通知B用户有个用户正在改数据?
DB2, SQL Server, Sybase因为没有回退段,回退靠Log实现,结果Log争抢激烈,再加上读一致性要求,带来特别多锁问题,开发人员要手工管理复杂的锁机制。Oracle没有这些问题,用不着开发人员管理锁,全自动。据我了解,开发那些数据库人员换用Oracle后,都感觉像脚踏车换成摩托车,甚至有人说Oracle的缺点是很难蹬着跑,哈哈。
DB2等数据库之所以有这么多个隔离级别和锁设置,主要是没有回退段而带来的开发和管理复杂性提高,并发行和读一致性无法兼顾。Oracle有回退段,并发行和读一致性都能兼顾,所以没有这方面的复杂性。
DB2和Oracle之间的比较就好比脚踏车和摩托车比较。脚踏车轻便,但是费劲;摩托车省力,但是多了个发动机。如果骑两种车的条件都具备,多数人会选择哪种车呢? [/B]
cliser 的例子中,“朋友正在存”,还没有提交,显而易见,储户本来就不应该看到朋友的未提交存款,所以,Oracle提供的不是“虚假的信息”,是可以对账的正确信息,所以,cliser的“储户就获得了虚假的信息”的结论是错误的。
假设这时候储户看到了朋友的存款,但是朋友又取消了存款,这种情况下储户看到的信息才是虚假信息。Oracle默认设置下是不会读到虚假信息的,而DB2在允许读取未提交信息的状态下会读出虚假信息(脏读,UR)。顺便说一句,Oracle通过设置一些少用的参数,也可以实现DB2的功能,例如UR,当然UR不是什么好功能。
兄弟,你说的这个有问题啊,ORACLE的一致读是说读到的东西以开始读的那时刻为准,和读的过程中其他会话操作数据是否提交没有关系啊.即便提交了,一致读的时候也是看没修改前的数据啊 |
|