简体   繁体   English

第一笔交易完成后,第二笔交易仍在等待中

[英]Second transaction remains waiting after the first completes

Running this same script in 2 windows in SSMS one after another with a couple of seconds' delay. 在SSMS的2个窗口中一次又一次地延迟运行同一脚本。
The second instance that I start later completes but the first one remains locked till I close the second window. 我稍后启动的第二个实例完成,但是第一个实例保持锁定状态,直到我关闭第二个窗口。 What is happening here? 这是怎么回事 Why is it not releasing the lock after the COMMIT? 为什么在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

Edit: 编辑:

The table structure is as follows: 表结构如下:

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]

You should update your question with the table structure. 您应该使用表结构更新您的问题。

As you did not specify whether your table has any index on it I assume there hasn't, ie dbo.t1 is a heap . 由于您没有指定表是否具有索引,所以我假设它没有索引,即dbo.t1heap

In this case you'll get classic deadlock : 在这种情况下,您将获得经典的deadlock

session1 wants to select from table and needs S for any row it reads and because there is no index on dbo.t1 the whole table is read and S-lock on the table is held for the whole duration of the transaction. session1希望从表中进行select ,并且需要S来读取它的任何行,并且因为dbo.t1上没有indexdbo.t1整个表都被读取,并且在事务的整个持续时间内,表上的S-lock被保留。

In meanwhile session2 does the same and it also acquires S-lock on the table and holds it. 同时, session2会执行相同的操作,并且还会在表上获取S-lock并将其保存。

Session1 now needs to convert its S-lock to IX in order to do update and it is blocked by session2 that holds S on dbo.t1 . Session1现在需要将其转换成S-lockIX为了做update ,它是通过阻断session2持有Sdbo.t1

When session2 tries to do the same it leads to deadlock because both sessions need IX and both are locked by other session. session2尝试执行相同操作时,这将导致死锁,因为两个会话都需要IX并且都被另一个会话锁定。

Here is the corresponding deadlock graph: 这是相应的死锁图:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 PlatformTransactionManager 完成事务后才提交插入 - Inserts not committed until after transaction completes using PlatformTransactionManager 如果客户端进程在事务启动后被终止,则数据库表保持锁定状态 - Database table remains locked, if client process is killed after transaction start 即使更改为完全恢复,事务日志仍保持60GB的大小 - Transaction Log remains 60GB size, even after changing to Full Recovery 在日期死亡后查找第一笔交易 - Finding first transaction after death of date 有关如何在第二个星期二之后编写第一个星期三的SQL日期维度 - SQL Date Dimension for how to write first Wednesday after second Tuesday 如何设置隔离级别,以便一个事务完成后,插入的数据可用于另一事务? - How do I set isolation levels so that once one transaction completes the inserted data is available to another transaction? 获取第一笔交易和最后一笔交易的价格 - get the price of the first transaction and last transaction SELECT 语句在 INSERT 提交事务后不会第一次返回行 - SELECT statement won't return row first time after INSERT commit transaction 死锁后重新提交事务 - Resubmit transaction after deadlock 交易后被阻止的数据 - Blocked data after transaction
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM