楼主: macrozeng

db2 与 Oracle 的锁的区别和比较

[复制链接]
论坛徽章:
0
21#
发表于 2007-6-28 13:46 | 只看该作者
关键是隔离级,数据库的并发要考虑隔离级。并发程序要解决的问题:

丢失更新:这种事件发生在两个事务读取和尝试更新同一数据时,其中一个更新会丢失。例如:事务 1 和事务 2 读取同一行数据,并都根据所读取的数据计算出该行的新值。如果事务 1 用其新值更新该行以后,事务 2 又更新了同一行,则事务 1 所执行的更新操作就丢失了。
脏读:当事务读取尚未提交的数据时,就会发生这种事件。例如:事务 1 更改了一行数据,而事务 2 在事务 1 提交更改之前读取了已更改的行。如果事务 1 回滚该更改,则事务 2 就会读取被认为是不曾存在的数据。
不可重复的读:当一个事务两次读取同一行数据,但每次获得不同的数据值时,就会发生这种事件。例如:事务 1 读取了一行数据,而事务 2 在更改或删除该行后提交了更改。当事务 1 尝试再次读取该行时,它会检索到不同的数据值(如果该行已经被更新的话),或发现该行不复存在了(如果该行被删除的话)。
幻像:当最初没有看到某个与搜索条件匹配的数据行,而在稍后的读操作中又看到该行时,就会发生这种事件。例如:事务 1 读取满足某个搜索条件的一组数据行,而事务 2 插入了与事务 1 搜索条件匹配的新行。如果事务 1 再次执行产生原先行集的查询,则会检索到不同的行集。

ANSI标准是4个隔离级,DB2遵循ANSI标准:
可重复的读(Repeatable Read)
读稳定性(Read Stability)
游标稳定性(Cursor Stability)
未提交的读(Uncommitted Read)

隔离级的选择是根据应用要解决的并发问题和并发性来平衡的,并没有唯一的标准。总结一下其实也很简单,都希望并发性大吧,那就问问可以容忍丢失更新吗,可以容忍脏读吗,可以容忍不可重复的读,可以容忍幻象吗?基本上每一个得到肯定回答,就可以往下走一个隔离级。

DB2和Oracle不同点是在于DB2缺省的隔离级是CS,而Oracle缺省有点象UR。
(1)既然有缺省的隔离级,对不缺省的隔离级是需要在语句或者session一级指定。Oracle也一样。大多数应用都是用CS。
(2)如果Oracle不在UR隔离级一样会有互锁问题。但是请注意这是数据库理论决定的,要解决上述所提到的并发问题就会引起互锁。
(3)在UR隔离级里,对于读什么样的脏数据ANSI标准并没有规定。DB2和大多数数据库是读最新的没有提交的脏数据,Oracle是读曾经提交过的数据(就是回滚段)。对这两种方法严格来说并没有谁好谁坏。

Oracle最经常举的例子:如果要统计12:00的数据,在12:00发命令就能真实得到12:00的数据,而没有未提交的数据。我的看法是如果应用真的需要在某个时间点的数据,应该由应用设计来保证。
比如你的老板让你统计截止12:00前的销售额,你统计了。老板问你准不准呀?你回答是看着时钟在12:00准时提交了个查询动作(不考虑应用程序响应和网络传输时间),并依靠Oralce产品的回滚段的特性得到了准确数据。你觉得老板的反映是什么?而如果应用设计里面有字段是保留销售时间,谓词用销售时间就可以得到真正准确的数据。

在一般的应用里回滚的数量要远远小于提交的数据量,而在一些应用里,是希望读到的数据要更接近最update的数据,也就是脏数据。

在大部分应用中真正要使用UR隔离级的,其实并不在乎读的数据是否包含脏数据还是曾经提交的数据。

所以对于并发控制来说,现在的关系性数据库已经很成熟了,只要合理的设置数据库参数,合理的设计应用是可以避免不必要的互斥操作。

使用道具 举报

回复
论坛徽章:
42
ITPUB元老
日期:2005-09-09 13:45:35马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14优秀写手
日期:2013-12-18 09:29:09ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32版主3段
日期:2012-05-15 15:24:112012新春纪念徽章
日期:2012-02-13 15:13:362012新春纪念徽章
日期:2012-02-13 15:13:36
22#
 楼主| 发表于 2007-6-28 17:23 | 只看该作者
讲得非常好!有个问题
我理解隔离级别中的 Uncommitted Read 是读未提交的,而 Oracle读曾经提交过的数据(就是回滚段)不应该算是 UR 的隔离级别吧?
在经典的事务例子中(例如银行转账),我觉得读最新的没有提交的脏数据比读回滚段要可怕很多。

使用道具 举报

回复
论坛徽章:
0
23#
发表于 2007-6-28 21:26 | 只看该作者
最初由 macrozeng 发布
[B]讲得非常好!有个问题
我理解隔离级别中的 Uncommitted Read 是读未提交的,而 Oracle读曾经提交过的数据(就是回滚段)不应该算是 UR 的隔离级别吧?
在经典的事务例子中(例如银行转账),我觉得读最新的没有提交的脏数据比读回滚段要可怕很多。 [/B]


所以说是类似DB2的UR,用Dirty read要准确些。不管它“曾经” “确定”存在过或“现在”“临时存”着在反正都是脏数据。

银行转账本身是经典的事务例子,用哪个隔离级去读它是另一个应用的事。虽然有可能在DB2 UR隔离级读两个帐户的总额有误,但是还是那句话,真正应用在用脏读隔离级去读的不会在乎读的是什么样的脏数据。

没见过涉及银行转账的哪个业务场景是一定需要在脏读隔离级用Oracle的回滚段特性。

使用道具 举报

回复
论坛徽章:
0
24#
发表于 2007-6-29 00:21 | 只看该作者
讲的很好,其实有时候往往需要在性能与准确性之间做一些取舍,技术总有其局限性,关键在如何恰当调整配合应用。

使用道具 举报

回复
论坛徽章:
42
ITPUB元老
日期:2005-09-09 13:45:35马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14优秀写手
日期:2013-12-18 09:29:09ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32版主3段
日期:2012-05-15 15:24:112012新春纪念徽章
日期:2012-02-13 15:13:362012新春纪念徽章
日期:2012-02-13 15:13:36
25#
 楼主| 发表于 2007-7-5 16:57 | 只看该作者
最初由 南来一味凉 发布
[B]

所以说是类似DB2的UR,用Dirty read要准确些。不管它“曾经” “确定”存在过或“现在”“临时存”着在反正都是脏数据。

银行转账本身是经典的事务例子,用哪个隔离级去读它是另一个应用的事。虽然有可能在DB2 UR隔离级读两个帐户的总额有误,但是还是那句话,真正应用在用脏读隔离级去读的不会在乎读的是什么样的脏数据。

没见过涉及银行转账的哪个业务场景是一定需要在脏读隔离级用Oracle的回滚段特性。 [/B]


我不同意你把 Oracle 默认的隔离级别 Read committed  也算做一种脏读,临时存在(Uncommitted Read) 可以认为是脏读,但是确定存在的 (Read committed)  不能算是脏读,就象我们不能否认历史一样。
举个不恰当的例子:如果一个人原来犯过错误,后来改正了。我们不能就认为他没有犯过错误,因为他的确是犯过错误。这就像是 Read committed,我们可以查出他确实犯过错误!
如果一个人仅仅头脑里面想象去抢银行,甚至做了周密的计划,但是他一直没有付诸行动,那我们如果查询出来他抢银行(Uncommitted Read)就是不合理的,这才是真正的脏读。

下面是 Oracle 官方文档对 Read committed  的解释
Read committed
This is the default transaction isolation level. Each query executed by a transaction sees only data that was committed before the query (not the transaction) began. An Oracle query never reads dirty (uncommitted) data.

Because Oracle does not prevent other transactions from modifying the data read by a query, that data can be changed by other transactions between two executions of the query. Thus, a transaction that runs a given query twice can experience both nonrepeatable read and phantoms.


summarizes key differences between read committed and serializable transactions in Oracle.

而且也明确指出  Dirty read  在 Read committed  这种隔离级别下是
Not possible  的。

IBM 对 Uncommitted Read 的定义也是 Also known as DIRTY READ ,May return data that is never committed to the database 。

所以说 Read committed  不能也被模糊地认为是一种  DIRTY READ。

使用道具 举报

回复
论坛徽章:
42
ITPUB元老
日期:2005-09-09 13:45:35马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14优秀写手
日期:2013-12-18 09:29:09ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32版主3段
日期:2012-05-15 15:24:112012新春纪念徽章
日期:2012-02-13 15:13:362012新春纪念徽章
日期:2012-02-13 15:13:36
26#
 楼主| 发表于 2007-7-5 17:30 | 只看该作者
大家还可以参考 ITPUB 杂志 ORACLE的隔离级别

http://epub.itpub.net/3/4.htm

里面明显区分了 read uncommitted 和 read committed

使用道具 举报

回复
论坛徽章:
21
在线时间
日期:2007-07-25 04:01:022012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:09:23
27#
发表于 2007-7-5 18:12 | 只看该作者
最初由 macrozeng 发布
[B]
谢谢,我只是觉得自己动手记忆会更深刻些 :)
文章我大概看了一下,大概意思是说 Oracle 的想法比较陈旧,而且不符合国际标准 :)由于 undo 的问题还会经常出现 ORA-01555 。而 DB2 是遵循标准。
其实,我无意对  DB2 和 Oracle 的好坏做出讨论,这个问题实在是太无聊,因为我本身是从 Oracle 转到 Db2 上了的,所以有很多 Oracle 的思维,在使用 Db2 的时候会去犯错误,我只想知道他们到底有什么区别,是因为什么原因造成这样的区别的?以后在使用不同的数据库的时候应该去注意点什么 :) [/B]


佩服佩服。

我最烦的就是ORACLE出的那些比较ORACLE跟其他的数据库的WHITE PAPER了。

使用道具 举报

回复
论坛徽章:
21
在线时间
日期:2007-07-25 04:01:022012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:09:23
28#
发表于 2007-7-5 18:18 | 只看该作者
最初由 macrozeng 发布
[B]讲得非常好!有个问题
我理解隔离级别中的 Uncommitted Read 是读未提交的,而 Oracle读曾经提交过的数据(就是回滚段)不应该算是 UR 的隔离级别吧?
在经典的事务例子中(例如银行转账),我觉得读最新的没有提交的脏数据比读回滚段要可怕很多。 [/B]


前不久去看电影,柜台的服务员跟我说可以给我某个号码的座位。我说OK,叫她出票。OOPS,等她一按,那座位已经被别人定了。

电影院允许这种情况,就是多个柜台的TRANSACTIONS没有SERIALIZE,但银行就不行了。我想ORACLE在这种情况下不会再用Read not block write/write not block the read了。好像THOMAS KYTE的某本书也有讲过这个问题。

使用道具 举报

回复
论坛徽章:
5
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44生肖徽章2007版:鸡
日期:2008-01-02 17:35:53生肖徽章2007版:鼠
日期:2008-01-02 17:35:532009新春纪念徽章
日期:2009-01-04 14:52:282011新春纪念徽章
日期:2011-02-18 11:43:33
29#
发表于 2007-7-5 20:48 | 只看该作者
最初由 macrozeng 发布
[B]

我不同意你把 Oracle 默认的隔离级别 Read committed  也算做一种脏读,临时存在(Uncommitted Read) 可以认为是脏读,但是确定存在的 (Read committed)  不能算是脏读,就象我们不能否认历史一样。
举个不恰当的例子:如果一个人原来犯过错误,后来改正了。我们不能就认为他没有犯过错误,因为他的确是犯过错误。这就像是 Read committed,我们可以查出他确实犯过错误!
如果一个人仅仅头脑里面想象去抢银行,甚至做了周密的计划,但是他一直没有付诸行动,那我们如果查询出来他抢银行(Uncommitted Read)就是不合理的,这才是真正的脏读。

下面是 Oracle 官方文档对 Read committed  的解释
Read committed
This is the default transaction isolation level. Each query executed by a transaction sees only data that was committed before the query (not the transaction) began. An Oracle query never reads dirty (uncommitted) data.

Because Oracle does not prevent other transactions from modifying the data read by a query, that data can be changed by other transactions between two executions of the query. Thus, a transaction that runs a given query twice can experience both nonrepeatable read and phantoms.


summarizes key differences between read committed and serializable transactions in Oracle.

而且也明确指出  Dirty read  在 Read committed  这种隔离级别下是
Not possible  的。

IBM 对 Uncommitted Read 的定义也是 Also known as DIRTY READ ,May return data that is never committed to the database 。

所以说 Read committed  不能也被模糊地认为是一种  DIRTY READ。 [/B]



顶 好像很有道理啊

使用道具 举报

回复
论坛徽章:
21
在线时间
日期:2007-07-25 04:01:022012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:09:23
30#
发表于 2007-7-5 22:23 | 只看该作者
个人认为就目前来讲,ORACLE的CONCURRENCY是会比DB2好些,但那是以牺牲一定的PERFORMANCE来换取的。

ORACLE必须保持UNDO来维持READ CONSISTENCY。而这个的代价是一个普通的QUERY可能得不停地往回滚,最终还可能ORA1555。

ORACLE还有一个很多时候没注意到的LOCKING,就是ITL LOCKING。虽然不是直接跟DATA本身有关,但一个DML没有ITL SLOT的话就根本没法执行。

可以做一个简单的测试。创建一个TABLE,把PCTFREE设成0,ITL不动。然后INSERT十万个数据。再从ROWID中选出4ROWS都在同一个BLOCK的。同时UPDATE这四个ROWS,你会发现只有两个UPDATE可以执行,另两个会在ITL WAITING。虽然这4ROWS都是互不关联的,但也会互相BLOCKING。等上十分钟,COMMIT其中一个已经UPDATE的SESSION,其中在ITL WAITING的一个UPDATE现在会被执行。再COMMIT这个UPDATE,结果会很惊奇地发现那个在ITL WAITING的还会继续ITL WAITING,虽然这时候已经有一个FREE ITL SLOT了。

这个就是ORACLE用DATA BLOCK来做LOCKING的一个副作用。

再说回DB2,可以确信若是做大量的数据处理的话,肯定会有很多BLOCKING的。但是感觉DB2在处理大量数据上比ORACLE有优势。所以即使有BLOCKING情况也未必很糟糕。

若是数据量不多的话,DB2的LOCKING还是很EFFICIENT的。所以DB2的APPLICATION DEVELOPMENT很强调COMMIT FREQUENCY。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表