死锁问题

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分送给答对的人。

...全文
196 38 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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)
《计算机操作系统》可作为计算机硬件和软件以及计算机通信专业的本科生教材,也可作为从事计算机及通信工作的相关科技人员的参考书。 目录 第一章 操作系统引论 1.1 操作系统的目标和作用 1 1.1.1 操作系统的目标 1 1.1.2 操作系统的作用 2 1.1.3 推动操作系统发展的主要动力 4 1.2 操作系统的发展过程 5 1.2.1 无操作系统的计算机系统 5 1.2.2 单道批处理系统 6 1.2.3 多道批处理系统 7 1.2.4 分时系统 9 1.2.5 实时系统 11 1.2.6 微机操作系统的发展 12 1.3 操作系统的基本特性 14 1.3.1 并发性 14 1.3.2 共享性 15 1.3.3 虚拟技术 16 1.3.4 异步性 17 1.4 操作系统的主要功能 18 1.4.1 处理机管理功能 18 1.4.2 存储器管理功能 19 1.4.3 设备管理功能 21 1.4.4 文件管理功能 21 1.4.5 操作系统与用户之间的接口 22 1.5 OS结构设计 24 1.5.1 传统的操作系统结构 24 1.5.2 客户/服务器模式 26 1.5.3 面向对象的程序设计 27 1.5.4 微内核OS结构 29 习题 33 第二章 进 程 管 理 2.1 进程的基本概念 34 2.1.1 程序的顺序执行及其特征 34 2.1.2 前趋图 35 2.1.3 程序的并发执行及其特征 36 2.1.4 进程的特征与状态 37 2.1.5 进程控制块 41 2.2 进程控制 43 2.2.1 进程的创建 43 2.2.2 进程的终止 45 2.2.3 进程的阻塞与唤醒 46 2.2.4 进程的挂起与激活 47 2.3 进程同步 47 2.3.1 进程同步的基本概念 47 2.3.2 信号量机制 50 2.3.3 信号量的应用 53 2.3.4 管程机制 55 2.4 经典进程的同步问题 58 2.4.1 生产者—消费者问题 58 2.4.2 哲学家进餐问题 61 2.4.3 读者—写者问题 63 2.5 进程通信 65 2.5.1 进程通信的类型 65 2.5.2 消息传递通信的实现方法 66 2.5.3 消息传递系统实现中的若干问题 68 2.5.4 消息缓冲队列通信机制 69 2.6 线程 71 2.6.1 线程的基本概念 72 2.6.2 线程间的同步和通信 75 2.6.3 线程的实现方式 77 2.6.4 线程的实现 78 习题 81 第三章 处理机调度与死锁 3.1 处理机调度的层次 84 3.1.1 高级调度 84 3.1.2 低级调度 86 3.1.3 中级调度 87 3.2 调度队列模型和调度准则 88 3.2.1 调度队列模型 88 3.2.2 选择调度方式和调度算法的若干准则 90 3.3 调度算法 91 3.3.1 先来先服务和短作业(进程)优先调度算法 91 3.3.2 高优先权优先调度算法 93 3.3.3 基于时间片的轮转调度算法 95 3.4 实时调度 97 3.4.1 实现实时调度的基本条件 97 3.4.2 实时调度算法的分类 99 3.4.3 常用的几种实时调度算法 100 3.5 产生死锁的原因和必要条件 103 3.5.1 产生死锁的原因 103 3.5.2 产生死锁的必要条件 105 3.5.3 处理死锁的基本方法 105 3.6 预防死锁的方法 106 3.6.1 预防死锁 106 3.6.2 系统安全状态 107 3.6.3 利用银行家算法避免死锁 108 3.7 死锁的检测与解除 111 3.7.1 死锁的检测 111 3.7.2 死锁的解除 113 习题 114 第四章 存 储 器 管 理 4.1 存储器的层次结构 116 4.1.1 多级存储器结构 116 4.1.2 主存储器与寄存器 117 4.1.3 高速缓存和磁盘缓存 117 4.2 程序的装入和链接 118 4.2.1 程序的装入 118 4.2.2 程序的链接 120 4.3 连续分配方式 121 4.3.1 单一连续分配 121 4.3.2 固定分区分配 122 4.3.3 动态分区分配 123 4.3.4 伙伴系统 126 4.3.5 哈希算法 126 4.3.6 可重定位分区分配 127 4.3.7 对换 129 4.4 基本分页存储管理方式 130 4.4.1 页面与页表 130 4.4.2 地址变换机构 131 4.4.3 两级和多级页表 133 4.5 基本分段存储管理方

22,300

社区成员

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

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