并发select for update引起死锁的问题

[复制链接]
查看11 | 回复9 | 2010-8-24 01:01:01 | 显示全部楼层 |阅读模式
现在有一个程序,大致情况如下:
insert into A values(每次数据不一样);
commit;
exec sql declare cur1 cursor for

select c1,c2,c3,c4,c5

fromA

where ...

order by c2, c3,c4

for update ;
然后open这个cursor
exec sql open cur1;
while(1)
{

fetch cur1 into :v1,:v2,:v3,:v4,:v5;

if(sqlca.sqlcode==notfound)break;
....
exec sql update A set c1=XX where current of cur1;
}
然后同时并发N个这样的程序,结果其中两个进程出现了deadlock,都锁在select c1,c2,c3,c4,c5fromAwhere ... order by c2, c3,c4for update 这句上面,是在open的时候死锁。
我知道for update会引起锁等待,这个没有问题,但现在是为什么会出现600死锁呢?因为前面的insert已经commit了,为什么会在open cursor的时候死锁呢?请各位帮忙指教
回复

使用道具 举报

千问 | 2010-8-24 01:01:01 | 显示全部楼层
既然都发生在open cursor的时候,那么这和前面的 insert 就没什么关系了吧,应该是 for update 产生的!


回复

使用道具 举报

千问 | 2010-8-24 01:01:01 | 显示全部楼层
谢谢红叶,但是这样两个并发的for update,我觉得只能是产生锁等待,为什么会产生死锁呢
回复

使用道具 举报

千问 | 2010-8-24 01:01:01 | 显示全部楼层
原帖由 seewell 于 2010-8-28 13:57 发表
谢谢红叶,但是这样两个并发的for update,我觉得只能是产生锁等待,为什么会产生死锁呢

如果是串行的锁,当然是产生锁等待了,但是你这个并不是嘛, for update 不仅在 table 上加锁,也会在for upfate 的 row 上加锁,
这样,如果两个程序中的行列锁发生了交叉等待,自然就是死锁了,
关于死锁的解决,可不能只是解决这个死锁就可以了,主要是要解决自锁产生的原因,从源头上解决。


回复

使用道具 举报

千问 | 2010-8-24 01:01:01 | 显示全部楼层
红叶,我试验过,并行两个这种select for update,并且是对同一个数据集操作,先提交的占用了资源,后来的进程会等待,不会产生死锁。
多个进程同时运行这个进程,数据就是交叉的,不然也不会用for update了,但是在这种交叉数据的情况下,运行都很正常(最多就是效率低了点)。但是最近出现了两次死锁,不知道为什么
回复

使用道具 举报

千问 | 2010-8-24 01:01:01 | 显示全部楼层
你说的“如果两个程序中的行列锁发生了交叉等待”,我也怀疑是这样,可是什么情况下select for update 会发生交叉等待呢?我怎么才能重现这个错误呢?
回复

使用道具 举报

千问 | 2010-8-24 01:01:01 | 显示全部楼层
原帖由 seewell 于 2010-8-28 17:04 发表
你说的“如果两个程序中的行列锁发生了交叉等待”,我也怀疑是这样,可是什么情况下select for update 会发生交叉等待呢?我怎么才能重现这个错误呢?

Oracle的锁有行级锁和表级锁嘛,而且死锁的情况哪能这么容易就出现了呢?
具体情况,你查看Oracle锁的相关文档吧!
回复

使用道具 举报

千问 | 2010-8-24 01:01:01 | 显示全部楼层
select for update 的时候加的是row级锁和table的share锁,只有在fetch之后,再对选出来的记录DML,table锁才会升级为。但是现在还没到DML那里呢
回复

使用道具 举报

千问 | 2010-8-24 01:01:01 | 显示全部楼层
锁升级和死锁也没什么必然联系把,我现在想重现这个错误,不知道怎么重现
回复

使用道具 举报

千问 | 2010-8-24 01:01:01 | 显示全部楼层
原帖由 seewell 于 2010-8-28 17:28 发表
锁升级和死锁也没什么必然联系把,我现在想重现这个错误,不知道怎么重现

锁升级 将会显著的增加死锁的可能性!比如 T1 事务 对 某数据资源的锁进行升级,同时T2 事务也拥有次数据资源的锁,如果此时T2 也需要将锁升级, 就会出现死锁!
回复

使用道具 举报

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

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行