查看: 9956|回复: 39

[精华] 请教两个DB2上的两个隔离/锁相关的问题

[复制链接]
论坛徽章:
0
跳转到指定楼层
1#
发表于 2009-8-3 10:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
第一个是在DB2 FOR LUW上面的:
现在有一个表deadtable, 只有一列C1(INT 4),同时在C1上定义了INDEX和KEY
现在里面有四条记录 11,22,33,44
        STEP 1.在线程A执行 +C UPDATE DEADTABLE SET C1=1 WHERE C1 = 11
        STEP 2.在线程B执行 +C SELECT * FROM DEADTABLE WHERE C1 =22
        STEP 3.在线程B执行 +C SELECT * FROM DEADTABLE WHERE C1 =33
        STEP 4.在线程B执行 +C SELECT * FROM DEADTABLE WHERE C1 =22 OR C1 =33
从偶的水平和接触到的资料来看,默认的Cursor Stability的情况下,update一条记录应该用的是行锁,不会影响其他纪录的查询或写入。
在上面的测试中,step 2,3确实也能正常的完成并得到结果。
问题处在step 4里面,当where条件中使用了or的时候,虽然按理说db2还是应该用index去直接找出这两行,但是实际上这个时候线程B却等待在了C1=11的行锁上。除非STEP1 中的线程A COMMIT,要不然线程 B会一直等待着。

而用
+C SELECT * FROM DEADTABLE WHERE C1=22
   UNION ALL
   SELECT * FROM DEADTABLE WHERE C1=33
去替换掉STEP 4的SQL的时候,又能正常返回了(这个时候其实和STEP2 ,3应该完全等价吧)

有哪位Boss能帮我解惑一下下么,where条件中的or是如何导致这个结果的阿?


第二个问题是处在db2 for mainframe上的:
分别在两个job里面提交下面的sql(当然先submit递归select的那个,然后再提交update)
SQL 1:
WITH TEMPTAB(CID, PID, LEVEL) AS                           
(     SELECT  CUSTID,PROVINCEID,1                           
      FROM    GDC272.GDC272_EMPLAB1                        
      WHERE   CUSTID =123                                   
         UNION ALL                                          
      SELECT  G.CUSTID,G.PROVINCEID,T.LEVEL+1               
      FROM    TEMPTAB T,     GDC272.GDC272_EMPLAB1 G        
      WHERE   T.LEVEL<1000000                              
      AND     G.CUSTID =123  
      AND     G.PROVINCEID = T.PROVINCEID
)
SELECT COUNT(*) FROM  TEMPTAB                              
                                                            
+

SQL 2:
UPDATE GDC272.GDC272_EMPLAB1                              
SET PROVINCEID =333            
WHERE CUSTID = 123      ;   

按理说默认游标级别的查询不加锁,UPDATE可以执行,但是这里却一直是因为等待时间过长而导致sqlcode=-911了。




然后再在db2 for LUW上,尝试在两个不同的线程里面提交和上面等价功能的sql:
SQL 1:
WITH TEMPTAB(C1,  LEVEL) AS                              
(     SELECT  C1,1                           
      FROM    DEADTABLE                          
      WHERE   C1 = 44                                    
         UNION ALL                                            
      SELECT  D.C1, T.LEVEL+1                 
      FROM    TEMPTAB T,     DEADTABLE D   
      WHERE   T.LEVEL<10000000                                 
      AND     D.C1 = 44   
)   
SELECT COUNT(*) FROM  TEMPTAB   

+

SQL 2:
UPDATE DEADTABLE SET C1 = 4 WHERE C1 = 44;
发现sql 2提交后,马上就完成了数据的修改,正在执行中的sql 1因为 C1=44的纪录已经被修改为4,所以递归SELECT中断,TEMPTAB中的纪录不到10000000 条


也就是说,这个代码在LUW上面能并发执行,但是在MAINFRAME上会导致死锁。
看了好多天,还是百思不得其解,盼高手解惑ING.
论坛徽章:
10
数据库板块每日发贴之星
日期:2009-06-04 01:01:02祖国60周年纪念徽章
日期:2009-10-09 08:28:002009日食纪念
日期:2009-07-22 09:30:00数据库板块每日发贴之星
日期:2009-06-28 01:01:02数据库板块每日发贴之星
日期:2009-06-15 01:01:02数据库板块每日发贴之星
日期:2009-06-14 01:01:02数据库板块每日发贴之星
日期:2009-06-09 01:01:02数据库板块每日发贴之星
日期:2009-06-07 01:01:02授权会员
日期:2009-06-06 10:43:16数据库板块每日发贴之星
日期:2010-12-01 01:01:01
2#
发表于 2009-8-3 10:21 | 只看该作者
如果是Oracle的话就什么事都没有了,DB2什么时候能在这个方面学习一下Oracle

使用道具 举报

回复
论坛徽章:
10
数据库板块每日发贴之星
日期:2009-06-04 01:01:02祖国60周年纪念徽章
日期:2009-10-09 08:28:002009日食纪念
日期:2009-07-22 09:30:00数据库板块每日发贴之星
日期:2009-06-28 01:01:02数据库板块每日发贴之星
日期:2009-06-15 01:01:02数据库板块每日发贴之星
日期:2009-06-14 01:01:02数据库板块每日发贴之星
日期:2009-06-09 01:01:02数据库板块每日发贴之星
日期:2009-06-07 01:01:02授权会员
日期:2009-06-06 10:43:16数据库板块每日发贴之星
日期:2010-12-01 01:01:01
3#
发表于 2009-8-3 10:29 | 只看该作者
你的第一个问题,我测试了没有问题

使用道具 举报

回复
论坛徽章:
0
4#
发表于 2009-8-3 10:40 | 只看该作者
第一个问题,应该是用OR的时间,数据库不使用索引,而用全表扫描,所以导致要锁定C1=11的记录,但此时记录已被别的程序所锁,导致了锁等待

使用道具 举报

回复
论坛徽章:
10
数据库板块每日发贴之星
日期:2009-06-04 01:01:02祖国60周年纪念徽章
日期:2009-10-09 08:28:002009日食纪念
日期:2009-07-22 09:30:00数据库板块每日发贴之星
日期:2009-06-28 01:01:02数据库板块每日发贴之星
日期:2009-06-15 01:01:02数据库板块每日发贴之星
日期:2009-06-14 01:01:02数据库板块每日发贴之星
日期:2009-06-09 01:01:02数据库板块每日发贴之星
日期:2009-06-07 01:01:02授权会员
日期:2009-06-06 10:43:16数据库板块每日发贴之星
日期:2010-12-01 01:01:01
5#
发表于 2009-8-3 10:50 | 只看该作者

回复 #4 winfoli 的帖子

应该不是那个原因

我测试的表没建索引,也是全表扫描,没有问题

使用道具 举报

回复
论坛徽章:
0
6#
发表于 2009-8-3 10:57 | 只看该作者
楼上你的数据库是默认隔离级别是什么

使用道具 举报

回复
论坛徽章:
0
7#
 楼主| 发表于 2009-8-3 11:01 | 只看该作者
不用索引的话确实不会出现这个问题,最开始的时候我没有在表上建key和index的时候就没有出现这个问题。
关于这点,有的资料上面说是:"如果被锁定的行本身不是用索引访问的,那么其他事务可以将新的行添加到表中,以及对被锁定行前后的行进行更新和/或删除操作"。

使用道具 举报

回复
论坛徽章:
0
8#
 楼主| 发表于 2009-8-3 11:01 | 只看该作者
to winfoli:
默认的是cs.

另外,有索引的时候也是全表扫描么?
我奇怪的是为什么我分开select或者用union的时候不会出现问题,而用or的话,就锁等待了

[ 本帖最后由 zhiliyang 于 2009-8-3 11:03 编辑 ]

使用道具 举报

回复
论坛徽章:
233
天枰座
日期:2016-02-02 09:36:332012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41灰彻蛋
日期:2011-06-22 19:28:30现任管理团队成员
日期:2011-05-07 01:45:082010广州亚运会纪念徽章:拳击
日期:2011-04-08 16:56:552011新春纪念徽章
日期:2011-02-18 11:43:332011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:15
9#
发表于 2009-8-3 11:02 | 只看该作者
用9.7吧

使用道具 举报

回复
论坛徽章:
0
10#
发表于 2009-8-3 11:04 | 只看该作者
楼上正解,那第二个问题呢

使用道具 举报

回复

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

本版积分规则 发表回复

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