第一个交易完成后,第二个交易仍在等待
Second transaction remains waiting after the first completes
运行 SSMS 中的 2 windows 中的相同脚本一个接一个地延迟几秒钟。
我稍后启动的第二个实例完成,但第一个实例保持锁定状态,直到我关闭第二个 window。
这里发生了什么?为什么COMMIT后不释放锁?
SET TRAN ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM dbo.t1
WHERE id IN (1,3)
WAITFOR DELAY '00:00:20'
UPDATE t1 SET InUse=0
WHERE id IN (1,3)
COMMIT
编辑:
table结构如下:
CREATE TABLE [dbo].[t1](
[id] [INT] NOT NULL,
[InUse] [BIT] NOT NULL DEFAULT ((0)),
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
您应该使用 table 结构更新您的问题。
因为你没有指定你的 table 是否有任何索引,我假设没有,即 dbo.t1
是 heap
.
在这种情况下,您将获得经典 deadlock
:
session1
想要从 table 到 select
并且它读取的任何行都需要 S
并且因为 [=11= 上没有 index
] 整个 table 被读取并且 table 上的 S-lock
在整个交易期间被持有。
与此同时,session2
做同样的事情,它也在 table 上获得 S-lock
并持有它。
Session1
现在需要将其 S-lock
转换为 IX
才能执行 update
并且它被持有 [=16 的 session2
阻止=] 在 dbo.t1
.
当 session2
尝试执行相同操作时会导致死锁,因为两个会话都需要 IX
并且都被其他会话锁定。
这里是对应的死锁图:
deadlock-list
deadlock victim=process155d1d498
process-list
process id=process155d1d498 taskpriority=0 logused=0 waitresource=OBJECT: 26:1765581328:0 waittime=16222 ownerId=5528849 transactionname=user_transaction lasttranstarted=2019-02-07T13:39:38.837 XDES=0x15ec1c3a8 lockMode=IX schedulerid=4 kpid=8140 status=suspended spid=54 sbid=0 ecid=0 priority=0 trancount=2 lastbatchstarted=2019-02-07T13:39:38.833 lastbatchcompleted=2019-02-07T13:39:38.833 lastattention=2019-02-07T13:38:49.187 clientapp=Microsoft SQL Server Management Studio - Query hostname=pppp hostpid=12276 loginname=FINCONSGROUP\anna.savchenko isolationlevel=serializable (4) xactid=5528849 currentdb=26 lockTimeout=4294967295 clientoption1=671098976 clientoption2=390200
executionStack
frame procname=adhoc line=9 stmtstart=248 stmtend=334 sqlhandle=0x02000000f445021276fec0f5ec119082f65611ce316a4d280000000000000000000000000000000000000000
UPDATE t1 SET InUse=0
WHERE id IN (1,3)
inputbuf
SET TRAN ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM dbo.t1
WHERE id IN (1,3)
WAITFOR DELAY '00:00:20'
UPDATE t1 SET InUse=0
WHERE id IN (1,3)
COMMIT
process id=process15649f868 taskpriority=0 logused=0 waitresource=OBJECT: 26:1765581328:0 waittime=1212 ownerId=5529084 transactionname=user_transaction lasttranstarted=2019-02-07T13:39:53.847 XDES=0x15ec1d048 lockMode=IX schedulerid=3 kpid=15516 status=suspended spid=57 sbid=0 ecid=0 priority=0 trancount=2 lastbatchstarted=2019-02-07T13:39:53.847 lastbatchcompleted=2019-02-07T13:39:53.847 lastattention=1900-01-01T00:00:00.847 clientapp=Microsoft SQL Server Management Studio - Query hostname=pppp hostpid=12276 loginname=FINCONSGROUP\anna.savchenko isolationlevel=serializable (4) xactid=5529084 currentdb=26 lockTimeout=4294967295 clientoption1=671098976 clientoption2=390200
executionStack
frame procname=adhoc line=9 stmtstart=248 stmtend=334 sqlhandle=0x0200000093b3ba1c08d586d1f142f473a7c8996074a369fc0000000000000000000000000000000000000000
UPDATE t1 SET InUse=0
WHERE id IN (1,3)
inputbuf
SET TRAN ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM dbo.t1
WHERE id IN (1,3)
WAITFOR DELAY '00:00:20'
UPDATE t1 SET InUse=0
WHERE id IN (1,3)
COMMIT
resource-list
objectlock lockPartition=0 objid=1765581328 subresource=FULL dbid=26 objectname=parts.dbo.t1 id=lock152c2d300 mode=S associatedObjectId=1765581328
owner-list
owner id=process15649f868 mode=S
owner id=process15649f868 mode=IX requestType=convert
waiter-list
waiter id=process155d1d498 mode=IX requestType=convert
objectlock lockPartition=0 objid=1765581328 subresource=FULL dbid=26 objectname=parts.dbo.t1 id=lock152c2d300 mode=S associatedObjectId=1765581328
owner-list
owner id=process155d1d498 mode=S
owner id=process155d1d498 mode=IX requestType=convert
waiter-list
waiter id=process15649f868 mode=IX requestType=convert
运行 SSMS 中的 2 windows 中的相同脚本一个接一个地延迟几秒钟。
我稍后启动的第二个实例完成,但第一个实例保持锁定状态,直到我关闭第二个 window。
这里发生了什么?为什么COMMIT后不释放锁?
SET TRAN ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM dbo.t1
WHERE id IN (1,3)
WAITFOR DELAY '00:00:20'
UPDATE t1 SET InUse=0
WHERE id IN (1,3)
COMMIT
编辑:
table结构如下:
CREATE TABLE [dbo].[t1](
[id] [INT] NOT NULL,
[InUse] [BIT] NOT NULL DEFAULT ((0)),
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
您应该使用 table 结构更新您的问题。
因为你没有指定你的 table 是否有任何索引,我假设没有,即 dbo.t1
是 heap
.
在这种情况下,您将获得经典 deadlock
:
session1
想要从 table 到 select
并且它读取的任何行都需要 S
并且因为 [=11= 上没有 index
] 整个 table 被读取并且 table 上的 S-lock
在整个交易期间被持有。
与此同时,session2
做同样的事情,它也在 table 上获得 S-lock
并持有它。
Session1
现在需要将其 S-lock
转换为 IX
才能执行 update
并且它被持有 [=16 的 session2
阻止=] 在 dbo.t1
.
当 session2
尝试执行相同操作时会导致死锁,因为两个会话都需要 IX
并且都被其他会话锁定。
这里是对应的死锁图:
deadlock-list
deadlock victim=process155d1d498
process-list
process id=process155d1d498 taskpriority=0 logused=0 waitresource=OBJECT: 26:1765581328:0 waittime=16222 ownerId=5528849 transactionname=user_transaction lasttranstarted=2019-02-07T13:39:38.837 XDES=0x15ec1c3a8 lockMode=IX schedulerid=4 kpid=8140 status=suspended spid=54 sbid=0 ecid=0 priority=0 trancount=2 lastbatchstarted=2019-02-07T13:39:38.833 lastbatchcompleted=2019-02-07T13:39:38.833 lastattention=2019-02-07T13:38:49.187 clientapp=Microsoft SQL Server Management Studio - Query hostname=pppp hostpid=12276 loginname=FINCONSGROUP\anna.savchenko isolationlevel=serializable (4) xactid=5528849 currentdb=26 lockTimeout=4294967295 clientoption1=671098976 clientoption2=390200
executionStack
frame procname=adhoc line=9 stmtstart=248 stmtend=334 sqlhandle=0x02000000f445021276fec0f5ec119082f65611ce316a4d280000000000000000000000000000000000000000
UPDATE t1 SET InUse=0
WHERE id IN (1,3)
inputbuf
SET TRAN ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM dbo.t1
WHERE id IN (1,3)
WAITFOR DELAY '00:00:20'
UPDATE t1 SET InUse=0
WHERE id IN (1,3)
COMMIT
process id=process15649f868 taskpriority=0 logused=0 waitresource=OBJECT: 26:1765581328:0 waittime=1212 ownerId=5529084 transactionname=user_transaction lasttranstarted=2019-02-07T13:39:53.847 XDES=0x15ec1d048 lockMode=IX schedulerid=3 kpid=15516 status=suspended spid=57 sbid=0 ecid=0 priority=0 trancount=2 lastbatchstarted=2019-02-07T13:39:53.847 lastbatchcompleted=2019-02-07T13:39:53.847 lastattention=1900-01-01T00:00:00.847 clientapp=Microsoft SQL Server Management Studio - Query hostname=pppp hostpid=12276 loginname=FINCONSGROUP\anna.savchenko isolationlevel=serializable (4) xactid=5529084 currentdb=26 lockTimeout=4294967295 clientoption1=671098976 clientoption2=390200
executionStack
frame procname=adhoc line=9 stmtstart=248 stmtend=334 sqlhandle=0x0200000093b3ba1c08d586d1f142f473a7c8996074a369fc0000000000000000000000000000000000000000
UPDATE t1 SET InUse=0
WHERE id IN (1,3)
inputbuf
SET TRAN ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM dbo.t1
WHERE id IN (1,3)
WAITFOR DELAY '00:00:20'
UPDATE t1 SET InUse=0
WHERE id IN (1,3)
COMMIT
resource-list
objectlock lockPartition=0 objid=1765581328 subresource=FULL dbid=26 objectname=parts.dbo.t1 id=lock152c2d300 mode=S associatedObjectId=1765581328
owner-list
owner id=process15649f868 mode=S
owner id=process15649f868 mode=IX requestType=convert
waiter-list
waiter id=process155d1d498 mode=IX requestType=convert
objectlock lockPartition=0 objid=1765581328 subresource=FULL dbid=26 objectname=parts.dbo.t1 id=lock152c2d300 mode=S associatedObjectId=1765581328
owner-list
owner id=process155d1d498 mode=S
owner id=process155d1d498 mode=IX requestType=convert
waiter-list
waiter id=process15649f868 mode=IX requestType=convert