+ -
当前位置:首页 → 问答吧 → 一个很疑惑的死锁问题求解

一个很疑惑的死锁问题求解

时间:2011-12-16

来源:互联网

最近数据库经常死锁,所以找了一下发现一个问题.求高手.
简单重现步骤:
A开启一个事物更新表里面主键ID是 123的记录 然后立马查询这个记录 事物不提交也不回滚
B去调用1个存储过程查询 记录是 234的记录.然后查询条件中有like 然后就死锁了
但是最恶心的如果查询这个234的记录语句不放在存储过程中那么就不会死锁.

A执行代码:
BEGIN TRAN

UPDATE [dbo].[DetailsOfCharge]
SET [LastOPDate] = GETDATE()
WHERE [DOCNo] = '123'

SELECT [t1].[DOCIndex]
FROM [dbo].[DetailsOfCharge] AS [t1]
WHERE @@ROWCOUNT > 0 AND [DOCNo] = '123'

B执行代码:
[ShareCharge] @SOANo = '2', @DOCNo = '234'

B的存储过程代码:
CREATE proc [dbo].[ShareCharge]
(
@SOANo char(30),
@DOCNo varchar (30)=''
)
as
BEGIN
SET NOCOUNT ON;
SET @DOCNo = '%' + @DOCNo
select * from DetailsOfCharge doc 
where doc.SoaNo = @SoaNo and doc.DOCNo LIKE @DOCNo
END


SOANo是主表主键 DOCNo是子表主键
子表的123和234 2条记录属于不同的主表记录
所以我就很郁闷了 这为什么会锁那?

作者: shangys1983   发布时间: 2011-12-16

作者: roy_88   发布时间: 2011-12-16

引用 1 楼 roy_88 的回复:

死锁分析
http://blog.csdn.net/roy_88/article/details/2686724

请看完再发.这不是一个标准的死锁.可以说是一个bug.存储过程中有问题,直接在查询分析器中执行无任何问题.

作者: shangys1983   发布时间: 2011-12-16

没有加锁
SET @DOCNo = '%' + @DOCNo
select * from DetailsOfCharge doc  
where doc.SoaNo = @SoaNo and doc.DOCNo LIKE @DOCNo
查询太慢吧

作者: ssp2009   发布时间: 2011-12-16

引用 2 楼 shangys1983 的回复:

引用 1 楼 roy_88 的回复:

死锁分析
http://blog.csdn.net/roy_88/article/details/2686724

请看完再发.这不是一个标准的死锁.可以说是一个bug.存储过程中有问题,直接在查询分析器中执行无任何问题.

有用心看麼?以上是SQL2005用索引可解決


作者: roy_88   发布时间: 2011-12-16

DetailsOfCharge 有索引嘛

作者: fanzhouqi   发布时间: 2011-12-16

另一种解決方法,用鎖的方式 

SQL code
--A
SELECT [t1].[DOCIndex]
FROM [dbo].[DetailsOfCharge] AS [t1] WITH (UPDLOCK)
WHERE @@ROWCOUNT > 0 AND [DOCNo] = '123'




SQL code
--B
select * from DetailsOfCharge doc WITH (UPDLOCK,READPAST)
where doc.SoaNo = @SoaNo and doc.DOCNo LIKE @DOCNo

作者: roy_88   发布时间: 2011-12-16

READPAST--為不讀取其他交易已鎖定的資料列和頁面
樓主可參照聯機,根據實現需求再指定

作者: roy_88   发布时间: 2011-12-16

这个问题已经解决了.
表里面索引全有.而且查询速度绝对很快.再慢也不可能慢出死锁来.
我是想知道为什么有人开了事物其他人在存储过程中用Like查询不先关的数据会死锁.
从存储过程中把语句拷贝出来相当快而且不死.

作者: shangys1983   发布时间: 2011-12-16

B存储过程里面就一个查询,也会死锁?

作者: ohfox   发布时间: 2011-12-16