死锁问题

Garnett_KG 2009-08-15 08:57:32


CREATE TABLE tb (
ID INT IDENTITY(1,1),
PK1 SMALLDATETIME,
PK2 CHAR(5),
PK3 CHAR(10),
DATA1 BIT,
DATA2 INT,
DATA3 VARCHAR(50) ,
CONSTRAINT PK_ID PRIMARY KEY NONCLUSTERED(ID)
)
GO

CREATE CLUSTERED INDEX CI_PK1_PK2_PK3 ON tb(PK1,PK2,PK3)

GO


INSERT INTO tb(PK1,PK2,PK3,DATA1,DATA2,DATA3)
SELECT '2009/08/15','A1','AAAA1',0,10,'Record 1'
UNION ALL
SELECT '2009/08/15','A1','AAAA2',0,10,'Record 2'
UNION ALL
SELECT '2009/08/15','A2','AAAA1',0,10,'Record 3'
UNION ALL
SELECT '2009/08/15','A2','AAAA2',0,10,'Record 4'
UNION ALL
SELECT '2009/08/15','A3','AAAA1',0,10,'Record 5'
UNION ALL
SELECT '2009/08/15','A3','AAAA2',0,10,'Record 6'
UNION ALL
SELECT '2009/08/14','B1','BBBBB1',0,10,'Record 7'
UNION ALL
SELECT '2009/08/14','B1','BBBBB2',0,10,'Record 8'
UNION ALL
SELECT '2009/08/14','B2','BBBBB1',0,10,'Record 9'
UNION ALL
SELECT '2009/08/14','B2','BBBBB2',0,10,'Record 10'
UNION ALL
SELECT '2009/08/14','B3','BBBBB1',0,10,'Record 11'
UNION ALL
SELECT '2009/08/14','B3','BBBBB2',0,10,'Record 12'


--Connection 1中执行:
BEGIN TRAN
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1'
--(1 行受影响)


--Connection 2中执行:
BEGIN TRAN
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2'
--(1 行受影响)

--返回Connection 1中执行
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK3='BBBBB2' AND DATA3='Record 12'
/*
--执行计划如下
1 1 UPDATE [tb] set [DATA1] = @1 WHERE [PK1]=@2 AND [PK3]=@3 AND [DATA3]=@4
1 1 |--Clustered Index Update(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SET:([tempdb].[dbo].[tb].[DATA1] = [Expr1004]))
0 0 |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(bit,[@1],0)))
1 1 |--Top(ROWCOUNT est 0)
1 1 |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SEEK:([tempdb].[dbo].[tb].[PK1]=CONVERT_IMPLICIT(smalldatetime,[@2],0)), WHERE:([tempdb].[dbo].[tb].[PK3]=[@3] AND [tempdb].[dbo].[tb].[DATA3]=[@4]) ORDERED FORWARD)

*/

--返回Connection 2中执行:
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK3='BBBBB1' AND DATA3='Record 9'
/*
--执行计划如下:
1 1 UPDATE [tb] set [DATA1] = @1 WHERE [PK1]=@2 AND [PK3]=@3 AND [DATA3]=@4
1 1 |--Clustered Index Update(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SET:([tempdb].[dbo].[tb].[DATA1] = [Expr1004]))
0 0 |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(bit,[@1],0)))
1 1 |--Top(ROWCOUNT est 0)
1 1 |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SEEK:([tempdb].[dbo].[tb].[PK1]=CONVERT_IMPLICIT(smalldatetime,[@2],0)), WHERE:([tempdb].[dbo].[tb].[PK3]=[@3] AND [tempdb].[dbo].[tb].[DATA3]=[@4]) ORDERED FORWARD)

*/

执行不久就会跳出死锁的信息,请问这是为什么?

300分送给答对的人。

...全文
192 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
Zoezs 2009-08-16
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 xman_78tom 的回复:]
会话 1 的第 1 条语句会请求并保持 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1' 索引键的 X 锁;
会话 2 的第 1 条语句会请求并保持 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 索引键的 X 锁;
会话 1 的第 2 条语句在请求  PK1='2009/08/14' AND PK2='B3' AND PK3='BBBBB2' 索引键的 X 锁时,会扫描索引页,由于在索引页上索引键 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 位于 PK1='2009/08/14' AND PK2='B3' AND PK3='BBBBB2' 前,因此 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 上的 X 锁会阻塞会话 1 扫描索引页,从而导致会话 1 的事务无法结束,释放 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1' 索引键的 X 锁;
会话 2 的第 2 条语句在请求  PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1' 索引键的 X 锁时,会被会话 1 阻塞,从而导致会话 2 的事务无法结束,释放 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 索引键的 X 锁。
这样便形成了循环死锁(Cycle Deadlock)。解决方法是更改会话 1 的事务中语句的执行顺序。
[/Quote]
你的意思是拿掉索引就OK?
xman_78tom 2009-08-16
  • 打赏
  • 举报
回复
会话 1 的第 1 条语句会请求并保持 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1' 索引键的 X 锁;
会话 2 的第 1 条语句会请求并保持 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 索引键的 X 锁;
会话 1 的第 2 条语句在请求 PK1='2009/08/14' AND PK2='B3' AND PK3='BBBBB2' 索引键的 X 锁时,会扫描索引页,由于在索引页上索引键 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 位于 PK1='2009/08/14' AND PK2='B3' AND PK3='BBBBB2' 前,因此 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 上的 X 锁会阻塞会话 1 扫描索引页,从而导致会话 1 的事务无法结束,释放 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1' 索引键的 X 锁;
会话 2 的第 2 条语句在请求 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1' 索引键的 X 锁时,会被会话 1 阻塞,从而导致会话 2 的事务无法结束,释放 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 索引键的 X 锁。
这样便形成了循环死锁(Cycle Deadlock)。解决方法是更改会话 1 的事务中语句的执行顺序。
Garnett_KG 2009-08-16
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 jonasfeng 的回复:]
引用楼主 garnett_kg 的回复:
SQL codeCREATETABLE tb (
    IDINTIDENTITY(1,1),
    PK1SMALLDATETIME,
    PK2CHAR(5),
    PK3CHAR(10),
    DATA1BIT,
    DATA2INT,
    DATA3VARCHAR(50) ,CONSTRAINT PK_IDPRIMARYKEYNONCLUSTERED(ID)
    )GOCREATECLUSTEREDINDEX CI_PK1_PK2_PK3ON tb(PK1,PK2,PK3)GOINSERTINTO tb(PK1,PK2,PK3,DATA1,DATA2,DATA3)SELECT'2009/08/15','A1','AAAA1',0,10,'Record 1'UNIONALLSELECT'2009/08/15','A1','AAAA2',0,10,'Record 2'UNIONALLSELECT'2009/08/15','A2','AAAA1',0,10,'Record 3'UNIONALLSELECT'2009/08/15','A2','AAAA2',0,10,'Record 4'UNIONALLSELECT'2009/08/15','A3','AAAA1',0,10,'Record 5'UNIONALLSELECT'2009/08/15','A3','AAAA2',0,10,'Record 6'UNIONALLSELECT'2009/08/14','B1','BBBBB1',0,10,'Record 7'UNIONALLSELECT'2009/08/14','B1','BBBBB2',0,10,'Record 8'UNIONALLSELECT'2009/08/14','B2','BBBBB1',0,10,'Record 9'UNIONALLSELECT'2009/08/14','B2','BBBBB2',0,10,'Record 10'UNIONALLSELECT'2009/08/14','B3','BBBBB1',0,10,'Record 11'UNIONALLSELECT'2009/08/14','B3','BBBBB2',0,10,'Record 12'
--Connection 1中执行:
BEGIN TRAN
    UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1'
--(1 行受影响)


--Connection 2中执行:
BEGIN TRAN
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2'
--(1 行受影响)

--返回Connection 1中执行
  UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14'  AND PK3='BBBBB2' AND DATA3='Record 12'
/*
--执行计划如下
1 1 UPDATE [tb] set [DATA1] = @1  WHERE [PK1]=@2 AND [PK3]=@3 AND [DATA3]=@4
1 1   |--Clustered Index Update(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SET:([tempdb].[dbo].[tb].[DATA1] = [Expr1004]))
0 0       |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(bit,[@1],0)))
1 1             |--Top(ROWCOUNT est 0)
1 1                 |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SEEK:([tempdb].[dbo].[tb].[PK1]=CONVERT_IMPLICIT(smalldatetime,[@2],0)),  WHERE:([tempdb].[dbo].[tb].[PK3]=[@3] AND [tempdb].[dbo].[tb].[DATA3]=[@4]) ORDERED FORWARD)

*/

--返回Connection 2中执行:
  UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14'  AND PK3='BBBBB1' AND DATA3='Record 9'
/*
--执行计划如下:
1 1 UPDATE [tb] set [DATA1] = @1  WHERE [PK1]=@2 AND [PK3]=@3 AND [DATA3]=@4
1 1   |--Clustered Index Update(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SET:([tempdb].[dbo].[tb].[DATA1] = [Expr1004]))
0 0       |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(bit,[@1],0)))
1 1             |--Top(ROWCOUNT est 0)
1 1                 |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SEEK:([tempdb].[dbo].[tb].[PK1]=CONVERT_IMPLICIT(smalldatetime,[@2],0)),  WHERE:([tempdb].[dbo].[tb].[PK3]=[@3] AND [tempdb].[dbo].[tb].[DATA3]=[@4]) ORDERED FORWARD)

*/

执行不久就会跳出死锁的信息,请问这是为什么?

300分送给答对的人。




楼主这问题还是比较容易判断的。
首先CONNECTION1 中的
SQL codebegintranUPDATE tbSET DATA1=1WHERE PK1='2009/08/14'AND PK2='B2'AND PK3='BBBBB2'
  虽然启动事务,但是楼主并没有提交,即COMMIT ,而事务会将表锁住。提交之后才会释放锁

接着楼主执行了CONNECTION2 中的
SQL codeBEGINTRANUPDATE tbSET DATA1=1WHERE PK1='2009/08/14'AND PK2='B2'AND PK3='BBBBB1'
  也启动了事务,但是该事务并未正常运行,因为他在等待CONNECTION1中把表的锁释放,因为UPDATE是独占锁。CONNECTION2 在等CONNECTION1 完成。

接下来楼主又执行了CONNECTION1中的一句
SQL codeUPDATE tbSET DATA1=1WHERE PK1='2009/08/14'AND PK3='BBBBB2'AND DATA3='Record 12'
这时候死锁就出现了。很简单,这个时候的SQL判断当前操作需要独占锁,而目前CONNECTION2 的锁还未释放。CONNECTION2的锁为什么没有释放呢。因为它在等最早执行的CONNECTION1的事务提交好释放锁。
如此一来,就形成了死循环,这不就是死锁吗?

解决方法也很简单:
connection1
SQL codeBEGINTRANUPDATE tbSET DATA1=1WHERE PK1='2009/08/14'AND PK2='B2'AND PK3='BBBBB2'COMMITTRAN

connection2
SQL codeBEGINTRANUPDATE tbSET DATA1=1WHERE PK1='2009/08/14'AND PK2='B2'AND PK3='BBBBB1'COMMITTRAN

加一个事务提交就OK了。
另外如果楼主不执行INSERT,UPDATE,DELETE 这类需要独占锁的语句,那么你的语句将不会有问题。
[/Quote]


呵呵,connection 1 的事务1没提交,并不意味着一定会阻塞Connection 2。 你可以试试下面的语句。

--Connection 1:

BEGIN TRAN
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1'
--(1 行受影响)

--Connection 2:
BEGIN TRAN
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2'
--(1 行受影响)



--返回connection 1:
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B3' AND PK3='BBBBB1' AND DATA3='Record 11'
--(1 行受影响)

--返回connection 2:
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B1' AND PK3='BBBBB1' AND DATA3='Record 7'

--(1 行受影响)






JonasFeng 2009-08-16
  • 打赏
  • 举报
回复
已经结贴了?
郁闷呀。
JonasFeng 2009-08-16
  • 打赏
  • 举报
回复
[Quote=引用楼主 garnett_kg 的回复:]
SQL codeCREATETABLE tb (
IDINTIDENTITY(1,1),
PK1SMALLDATETIME,
PK2CHAR(5),
PK3CHAR(10),
DATA1BIT,
DATA2INT,
DATA3VARCHAR(50) ,CONSTRAINT PK_IDPRIMARYKEYNONCLUSTERED(ID)
)GOCREATECLUSTEREDINDEX CI_PK1_PK2_PK3ON tb(PK1,PK2,PK3)GOINSERTINTO tb(PK1,PK2,PK3,DATA1,DATA2,DATA3)SELECT'2009/08/15','A1','AAAA1',0,10,'Record 1'UNIONALLSELECT'2009/08/15','A1','AAAA2',0,10,'Record 2'UNIONALLSELECT'2009/08/15','A2','AAAA1',0,10,'Record 3'UNIONALLSELECT'2009/08/15','A2','AAAA2',0,10,'Record 4'UNIONALLSELECT'2009/08/15','A3','AAAA1',0,10,'Record 5'UNIONALLSELECT'2009/08/15','A3','AAAA2',0,10,'Record 6'UNIONALLSELECT'2009/08/14','B1','BBBBB1',0,10,'Record 7'UNIONALLSELECT'2009/08/14','B1','BBBBB2',0,10,'Record 8'UNIONALLSELECT'2009/08/14','B2','BBBBB1',0,10,'Record 9'UNIONALLSELECT'2009/08/14','B2','BBBBB2',0,10,'Record 10'UNIONALLSELECT'2009/08/14','B3','BBBBB1',0,10,'Record 11'UNIONALLSELECT'2009/08/14','B3','BBBBB2',0,10,'Record 12'
--Connection 1中执行:
BEGIN TRAN
    UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1'
--(1 行受影响)


--Connection 2中执行:
BEGIN TRAN
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2'
--(1 行受影响)

--返回Connection 1中执行
  UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14'  AND PK3='BBBBB2' AND DATA3='Record 12'
/*
--执行计划如下
1 1 UPDATE [tb] set [DATA1] = @1  WHERE [PK1]=@2 AND [PK3]=@3 AND [DATA3]=@4
1 1   |--Clustered Index Update(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SET:([tempdb].[dbo].[tb].[DATA1] = [Expr1004]))
0 0       |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(bit,[@1],0)))
1 1             |--Top(ROWCOUNT est 0)
1 1                 |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SEEK:([tempdb].[dbo].[tb].[PK1]=CONVERT_IMPLICIT(smalldatetime,[@2],0)),  WHERE:([tempdb].[dbo].[tb].[PK3]=[@3] AND [tempdb].[dbo].[tb].[DATA3]=[@4]) ORDERED FORWARD)

*/

--返回Connection 2中执行:
  UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14'  AND PK3='BBBBB1' AND DATA3='Record 9'
/*
--执行计划如下:
1 1 UPDATE [tb] set [DATA1] = @1  WHERE [PK1]=@2 AND [PK3]=@3 AND [DATA3]=@4
1 1   |--Clustered Index Update(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SET:([tempdb].[dbo].[tb].[DATA1] = [Expr1004]))
0 0       |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(bit,[@1],0)))
1 1             |--Top(ROWCOUNT est 0)
1 1                 |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[tb].[CI_PK1_PK2_PK3]), SEEK:([tempdb].[dbo].[tb].[PK1]=CONVERT_IMPLICIT(smalldatetime,[@2],0)),  WHERE:([tempdb].[dbo].[tb].[PK3]=[@3] AND [tempdb].[dbo].[tb].[DATA3]=[@4]) ORDERED FORWARD)

*/

执行不久就会跳出死锁的信息,请问这是为什么?

300分送给答对的人。


[/Quote]

楼主这问题还是比较容易判断的。
首先CONNECTION1 中的
begin tran 
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2'

虽然启动事务,但是楼主并没有提交,即COMMIT ,而事务会将表锁住。提交之后才会释放锁。

接着楼主执行了CONNECTION2 中的
BEGIN TRAN 
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1'

也启动了事务,但是该事务并未正常运行,因为他在等待CONNECTION1中把表的锁释放,因为UPDATE是独占锁。CONNECTION2 在等CONNECTION1 完成。

接下来楼主又执行了CONNECTION1中的一句
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14'  AND PK3='BBBBB2' AND DATA3='Record 12'

这时候死锁就出现了。很简单,这个时候的SQL判断当前操作需要独占锁,而目前CONNECTION2 的锁还未释放。CONNECTION2的锁为什么没有释放呢。因为它在等最早执行的CONNECTION1的事务提交好释放锁。
如此一来,就形成了死循环,这不就是死锁吗?

解决方法也很简单:
connection1
BEGIN TRAN 
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2'
COMMIT TRAN


connection2
BEGIN TRAN 
UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1'
COMMIT TRAN


加一个事务提交就OK了。
另外如果楼主不执行INSERT,UPDATE,DELETE 这类需要独占锁的语句,那么你的语句将不会有问题。
Garnett_KG 2009-08-16
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 zoezs 的回复:]
引用 32 楼 xman_78tom 的回复:
会话 1 的第 1 条语句会请求并保持 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1' 索引键的 X 锁;
会话 2 的第 1 条语句会请求并保持 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 索引键的 X 锁;
会话 1 的第 2 条语句在请求  PK1='2009/08/14' AND PK2='B3' AND PK3='BBBBB2' 索引键的 X 锁时,会扫描索引页,由于在索引页上索引键 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 位于 PK1='2009/08/14' AND PK2='B3' AND PK3='BBBBB2' 前,因此 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 上的 X 锁会阻塞会话 1 扫描索引页,从而导致会话 1 的事务无法结束,释放 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1' 索引键的 X 锁;
会话 2 的第 2 条语句在请求  PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1' 索引键的 X 锁时,会被会话 1 阻塞,从而导致会话 2 的事务无法结束,释放 PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2' 索引键的 X 锁。
这样便形成了循环死锁(Cycle Deadlock)。解决方法是更改会话 1 的事务中语句的执行顺序。

你的意思是拿掉索引就OK?
[/Quote]


分析差不多都对了,但解决方法说的不对。
可能又要到下星期天才有时间上来,我先结帖好了。

xman_78tom 2009-08-16
  • 打赏
  • 举报
回复
拿掉索引也不一定有用,因为行锁更有可能阻塞对数据页面的扫描。就你这种情况而言,更改会话 1 的事务中语句的执行顺序是最好的方法。
ks_reny 2009-08-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 liangck 的回复:]
300分送给答对的人。

---------------
不喜欢这一点.
[/Quote]
楼主知道答案?让大家猜?
feixianxxx 2009-08-15
  • 打赏
  • 举报
回复
参合
Garnett_KG 2009-08-15
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 zoezs 的回复:]
引用 26 楼 garnett_kg 的回复:
引用 24 楼 zoezs 的回复:
KG哥,你把你的主键拿掉,试试。我拿掉主键就不会产生死锁了。


拿掉主键其实会更容易发生死锁,是时机点的问题。你不用WAITFOR 而该成手动控制执行顺序试试。


但是如果第一个事务结束,第二个事务马上就会执行OK。
可能是锁表了。
[/Quote]

是的。
Zoezs 2009-08-15
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 garnett_kg 的回复:]
引用 24 楼 zoezs 的回复:
KG哥,你把你的主键拿掉,试试。我拿掉主键就不会产生死锁了。



拿掉主键其实会更容易发生死锁,是时机点的问题。你不用WAITFOR 而该成手动控制执行顺序试试。

[/Quote]
但是如果第一个事务结束,第二个事务马上就会执行OK。
可能是锁表了。
Garnett_KG 2009-08-15
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 ws_hgo 的回复:]
很久不见KG
[/Quote]
HI果果。
Garnett_KG 2009-08-15
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 zoezs 的回复:]
KG哥,你把你的主键拿掉,试试。我拿掉主键就不会产生死锁了。

[/Quote]

拿掉主键其实会更容易发生死锁,是时机点的问题。你不用WAITFOR 而该成手动控制执行顺序试试。
ws_hgo 2009-08-15
  • 打赏
  • 举报
回复
很久不见KG
Zoezs 2009-08-15
  • 打赏
  • 举报
回复
KG哥,你把你的主键拿掉,试试。我拿掉主键就不会产生死锁了。
Garnett_KG 2009-08-15
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 zoezs 的回复:]
这样第二个connection执行了很长的时间,依然没有完成。
[/Quote]

加ROWLOCK 或是NOLOCK ,deadlock 依然是存在的,你可以跑多几次看看。
ai_li7758521 2009-08-15
  • 打赏
  • 举报
回复
学习
Zoezs 2009-08-15
  • 打赏
  • 举报
回复
这样第二个connection执行了很长的时间,依然没有完成。
Zoezs 2009-08-15
  • 打赏
  • 举报
回复

--第一个connection
BEGIN TRAN
UPDATE tb1 with (rowlock) SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB1'
waitfor delay '00:00:10'
UPDATE tb1 with (rowlock) SET DATA1=1 WHERE PK1='2009/08/14' AND PK3='BBBBB2' AND DATA3='Record 12'
commit tran

--第二个connection
BEGIN TRAN
UPDATE tb1 with (rowlock) SET DATA1=1 WHERE PK1='2009/08/14' AND PK2='B2' AND PK3='BBBBB2'
waitfor delay '00:00:10'
UPDATE tb1 with (rowlock) SET DATA1=1 WHERE PK1='2009/08/14' AND PK3='BBBBB1' AND DATA3='Record 7'
commit tran


Zoezs 2009-08-15
  • 打赏
  • 举报
回复
改了下,试了下,果然还是有死锁。

UPDATE tb SET DATA1=1 WHERE PK1='2009/08/14' AND PK3='BBBBB1' AND DATA3='Record 7'

我再来试一下手动加锁
加载更多回复(18)

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧