77范文网 - 专业文章范例文档资料分享平台

DB2隔离级别和锁 - 图文(9)

来源:网络收集 时间:2020-02-21 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

设第二条语句是“ db2 select * form t1 where id=11 ”。在此情况下,即使 Session 2 与列 ID=22 中的任何值 ( 还没有被提交 ) 都没有关系,它也仍将被阻塞,处于锁等待 (LOCK WAIT) 状态。在 DB2 中,默认情况下将发生这一系列的事件,因为默认的隔离级别是 CS 。这种隔离级别表明,一个查询访问的任何一行在游标定位到该行时都必须被锁定。在语句 1 释放它用于更新表 T1 的锁之前,语句 2 不能包含表 T1 第一行上的锁。如果 DB2 知道 ID=11 值不是语句 2 的数据请求的一部分 ( 换句话说,它在锁行之前计算了谓词 ),那么就可以避免阻塞,这是合情合理的,因为语句 2 将不会尝试锁定表中的第一行。 现在我们启用 DB2_EVALUNCOMMITTED 注册变量,该实例设置后需要重启实例才能生效,输出结果如下: db2set DB2_EVALUNCOMMITTED=ON – i db2stop force db2start

在启用该实例后,再重复刚才的实验,我们发现第二条 SQL 语句“ select * from t1 where id=11 ”可以执行而不会被阻塞。所以 DB2_EVALUNCOMMITTED 注册变量的作用是判断该 SQL 谓词所扫描的行是否有锁,如果没有就可以检索到数据。

EVAL UATE UNCOMMITTED 第一次在 DB2 V8.1.4 中被引入时,带有以下限制:

? ? ? ? ? ?

该特性只能用于 CS 和 RS 隔离级别。 SARGABLE 谓词必须存在,以便计算。 不适用于系统编目表上的扫描。

当扫描一个 MDC 表时,对于索引扫描,块锁可以推迟。然而,对于表扫描,块锁不会推迟。 被推迟的锁不会发生在正在执行在线表重组的表上。

INDEX MANAGER 不可能在没有锁行的情况下回调 DATA MANAGER 来取数据记录。这意味着 ISCAN-FETCH 计划不能在 DATA MANAGER 中推迟锁 ( 唯一的例外是对一个 MDC 表的块索引,它的 INDEX EVALUATION 谓词是一个 ISCAN 计划 ) 。

DB2 V8.2.2 通过去掉 DB2 V8.1.4 中第一阶段的 EVAL UATE UNCOMMITTED,改进了这些缺点。 DB2 V8.2.2 引入了名为 DEFERISCANFETCH 的注册表变量,作为 DB2_EVALUNCOMMITTED 的新设置。启用该变量时,由该特性承担的锁将避免使用 ISCAN-FETCH 数据读取。

DB2_EVALUNCOMMITTED 注册变量影响 DB2 在游标稳定性 (CS) 和读稳定性 (RS) 隔离级别下的行锁机制。当你启用该功能时,DB2 可以对未提交的插入 (INSERT) 或者更新 (UPDATE) 数据进行谓词判断,如果未提交数据不符合这条语句的谓词判断条件,DB2 将不对未提交数据加锁。这样就避免了因为要对未提交数据加锁而引起的锁等待状态,提高了应用程序访问的并发性,同时 DB2 在无条件进行表扫描时会忽略删除的行数据 ( 不管是否提交 ) 。

这里分两种情况来看待。第一种情况:对于插入 (INSERT) 或者更新 (UPDATE),如果未提交数据不符合这条语句的谓词判断条件,DB2 将不对未提交数据加锁。这样虽然比不上 Oracle 对于符合这条语句的谓词判断条件可以从回滚段里面读出 BEFORE IMAGE 那样做到写不阻止读,但是起码一定程度上缓解了锁的问题,不会因为插入 (INSERT) 或者更新 (UPDATE) 一条记录造成整个表都锁住。这点是个进步,我个人觉得也不会造成什么大的负面影响。

下面我们通过一个实验来说明这点,输出结果如下:

db2 create table t1(id int) db2 insert into t1 values(11) db2 insert into t1 values(22) db2 commit 现在表中有两条记录 11 和 22

现在有两个 Session 发出了下面的 SQL 语句,输出结果如下: Session 1 Session 2 db2 CONNECT TO SAMPLE db2 +c delete from t1 where id=22 db2 CONNECT TO SAMPLE db2 SELECT * FROM t1 WHERE id=11 在未设置 DB2_EVALUNCOMMITTED=ON 时,Session 2 肯定是处于锁等待 (LOCKWAIT) 状态的,现在我们设置了 DB2_EVALUNCOMMITTED=ON 后,我们来看看 Session 2 能否检索到数据,输出结果如下: Session 1 Session 2 db2 CONNECT TO SAMPLE db2 +c delete from t1 where id=22 db2 CONNECT TO SAMPLE C:\\>db2 select * from t1 11 1 条记录已选择。 ID ----------- 第二种情况是:通过上面的实验我们发现在启用 DB2_EVALUNCOMMITTED=ON 时,对于 DELETE 操作,DB2 在无条件进行表扫描时会忽略删除的行数据 ( 不管是否提交 ) 。个人觉得有很大的问题,通过上面的这个测试,一个会话删除一条记录并没有提交,另外一个会话查询的时候已经没有这条记录了,这相当于 UR 隔离级别。这样显然是不符合业务要求的。与其这样还不如锁住。所以启用 DB2_EVALUNCOMMITTED=ON 时,对于删除操作应该注意多多测试。 现在我们在 T1 上创建一个 type-2 的索引,然后再来做刚才的那个实验: db2 create index index11 on t1(id) 在两个命令行窗口中分别发出下面的 SQL 语句: Session 1 Session 2 db2 CONNECT TO SAMPLE id=22 db2 CONNECT TO SAMPLE db2 create index index11 on t1(id) db2 +c delete from t1 where C:\\>db2 select * from t1 --lockwait 挂起

我们在另外一个窗口查看 Session 2 的状态,发现 Session 2 处于 LOCKWAIT 状态,输出结果如图 6-8 所示。

图 6-8 查看 Session 2 的状态

当您的 DB2 环境中启用了 EVAL UATE UNCOMMITTED 行为时,您应该清楚,谓词计算可能发生在未提交的数据上。而且,在表扫描访问中,被删除行会被无条件忽略,而对于 type-2 索引扫描,被删除的键不会被忽略 ( 除非您还设置了 DB2_SKIPDELETED 注册表变量,DB2_SKIPDELETED 变量我们稍后介绍 ) 。如果您要在 DB2 环境中单独设置 DB2_SKIPDELETED 注册表变量,DB2 将允许在表扫描访问时无条件地忽略被删除行,并忽略 type-2 索引扫描访问的伪删除索引键。 6.5.2 DB2_SKIPDELETED DB2_SKIPDELETED 变量被启用时,将允许使用 CS 或 RS 隔离级别的语句在索引扫描期间无条件地跳过被删除的键,而在表访问期间则无条件地跳过被删除的行。当DB2_EVALUNCOMMITTED被启用时,被删除的行会被自动跳过,但是除非同时启用了DB2_SKIPDELETED,否则 type-2 索引中未提交的伪删除键不会被跳过。 在上面的实验中,我们发现当我们设置了DB2_EVALUNCOMMITTED 变量时,如果表上有 type-2 索引,那么在我们读取数据时,被删除的索引键不会被忽略。这种情况下如果你希望跳过被删除的键,可以通过设置 DB2_SKIPDELETED=ON 来实现,下面我们做个实验,输出结果如下: db2set DB2_SKIPDELETED=ON – i db2stop force db2start 设置生效后,我们接着做刚才的实验,输出结果如下: Session 1 Session 2 db2 CONNECT TO SAMPLE db2 CONNECT TO SAMPLE db2 create index index11 on t1(id) C:\\>db2 select * from t1 ---DB2 V8 后创建的索引默认都是 type-2 ID db2 +c delete from t1 where id=22 ----------- 11 1 条记录已选择。

我们可以看到在设置 DB2_SKIPDELETED=ON 后,即使 T1 表上有 type-2 索引,扫描的时候也仍然忽略这个删除的行。但是这个在用的时候一定要结合业务逻辑使用,因为这种情况下等同于“脏读”,所以一定多测试。

6.5.3 DB2_SKIPINSERTED

虽然当一个行由于一个未提交的 INSERT 而被锁的时候,这种行为是正确的,但是有些情况下应用程序的所有者希望 DB2 忽略正在等待提交的被插入的行,就好像它不存在一样 ( 由于未提交 INSERT 的提交版本现在根本没有行,所以这是可能的 ) 。例如,银行在下午 5 点左右想统计今天的业务量,这时只是想了解大概的业务量而不是精确的,这种情况下如果启用该变量,那么遗漏一两笔业务是可以接受的。 在 DB2 V8.2.2 中,DB2_SKIPINSERTED=OFF 是默认设置。这使得 DB2 的行为和预期的一样:扫描器一直等到 INSERT 事务提交或回滚,然后返回数据。是否打开该变量取决于您的应用程序以及和业务逻辑相关的数据完整性的特征,这样可能合适,也可能不合适。例如,考虑一个涉及两个应用程序的业务流程,这两个应用程序使用相同的一个表来交换业务信息,例如一个信用评级应用程序和一个信用评分引擎。应用程序 A 基于一个 Web 表单将数据插入数据库,应用程序 B 读这些数据。为了加快信用审批的速度,由于候选者通过信用评级应用程序来进行表单转移,信息块通过表单中的“ STEPS ”被发送到应用程序 B( 通过公共的表 ) 。当候选者完成信用评级应用程序流程中的每个步骤时,信息被发送。在这个环境中,数据必须由第二个应用程序按照表中给出的顺序来处理,以便当接下来要读的行要被应用程序 A 插入时,应用程序 B 必须等待,直到 INSERT 被提交。

如果设置 DB2_SKIPINSERTED=ON,DB2 将把未提交的 INSERT( 只适于 CS 和 RS 隔离级别 ) 看作它们还没有被插入。该特性增加了并发性,同时又不牺牲隔离语义。 DB2 为扫描器实现了这种能力,通过锁属性和锁请求的反馈,使其忽略未提交的插入行,而不是等待。 下面我们来看看设置 DB2_SKIPINSERTED 变量前后的对比,输出结果如下:

Session 1 Session 2

db2 CONNECT TO SAMPLE db2 CONNECT TO SAMPLE

db2 create index index11 on t1(id) C:\\>db2 select * from t1 db2 reorg indexes all for table -- 挂起,处于 lockwait 状态 DB2ADMIN.t1 convert

db2 +c insert into t1 values(33)

通过监控发现 Session 2 处于 LOCKWAIT 状态,输出结果如图 6-9 所示。

图 6-9 查看 Session 2 的状态

如果这种情况下 Session 2 希望能够跳过未提交 INSERT 的数据而得到数据,那么可以设置 DB2_SKIPINSERTED 注册变量,输出结果如下: db2set DB2_SKIPINSERTED=ON – i db2stop force db2start 在设置 DB2_SKIPINSERTED=ON 后,再重复刚才的实验,我们发现这个时候,Session 2 可以读到数据,输出结果如下: Session 1 Session 2 db2 CONNECT TO SAMPLE C:\\>db2 select * from t1 db2 create index index11 on t1(id) ID db2 reorg indexes all for table ----------- DB2ADMIN.t1 convert 11 db2 +c insert into t1 values(33) 22 2 条记录已选择。

DB2_EVALUNCOMMITTED、DB2_SKIPDELETED 和 DB2_SKIPINSERTED 总结

总的来说这 3 个注册变量会影响到并发性。通过合理设置这些变量可以改善并发性,但是也会影响到应用程序的行为。建议在 DB2 开发设计的初期启用这些注册变量,从而在实现并发性增强后执行全面测试中的所有单元测试。

通过对这三个注册变量进行设置,可以提高并发,但是我们使用的时候一定要结合自己的业务逻辑使用。根据个人的经验,我建议使用 DB2_EVALUNCOMMITTED=ON 和 DB2_SKIPINSERTED=ON,对于 DB2_SKIPDELETED 变量,使用的时候一定要充分地测试,因为它等同于使用 UR 隔离级别 ( 注:虽然 DB2_SKIPINSERTED=ON 也等同于 UR,但是没有插入的数据反正也没有插入,读不到数据在业务上是可以接受的 ) 。

总之,有了这三个变量,我们多了一份选择总比没有强。目前这三个变量都是实例级别的变量,如果能做成 SQL 级或应用级的就更好了。期待 DB2 能够在后续的版本中继续对锁并发作出改进。

回页首

6.6 本章小结

数据库中锁的技术是数据库系统中的一个核心技术,它决定了数据库中访问数据的最基本的方式和手段。所以对于 DBA 来说,掌握数据库的锁技术是掌握数据库技术时必不可少的内容。

本章我们介绍了 DB2 中关于锁的一些高级内容。锁对数据库的并发影响很大,掌握锁的这些相关的技术对于我们合理地设计数据库和应用程序以保证提高数据库的并发性能具有重大意义。锁同样对数据的一致性也有很大的影响,使用不同的隔离级别策略来保证应用程序在访问 DB2 中数据的过程中所必须的数据一致性需求也显得很重要。虽然这两者都很重要,但遗憾的是数据库中数据的并发性和一致性始终是一对矛盾,如何调和这两者的关系在应用设计和数据库设计中就显得极为重要。首先考虑的因素是应用的需求,然后要考虑的就是数据库能够提供的技术手段。 DB2 的锁技术现在越来越灵活、越来越强大,通过使用本章介绍的这些高级技术或者新的锁功能,基本上都能够实现我们各种各样的数据访问中的锁需求。那么相对来说的更灵活且不易确定的就是应用中对锁的需求到底是怎样的?这就需要系统设计人员能够洞悉应用的需求,从需求定义中释出合理的锁需求,这同样也是我们要掌握的技术。本章还详细介绍了 DB2 提供的实现上述两种需求的各种高级技术和新功能,而且通过大量的例子为我们演示了这些技术的使用方法和技巧。这都为更好地掌握 DB2 的锁技术铺平了道路。

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库DB2隔离级别和锁 - 图文(9)在线全文阅读。

DB2隔离级别和锁 - 图文(9).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/jiaoyu/783370.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: