我的一个过程有一个很大的问题(我没有设计它......无论是谁......)
我有多线程(1-50)进程,执行两个存储过程:
- 从客户端表中读取数据
- 从客户端表中删除数据
我已经设法获得INDEX SCAN而不是TABLE SCAN,它工作得相当快(它不会变得更快)。有时我会因删除SELECT锁而获得DEADLOCKs,这是可以理解的。
至今:
- 性能优化扫描索引而不是表
- ROW_ESCALATION改为DISABLED(它有很多帮助)
任何想法如何摆脱U锁/死锁?
更多信息和日志
05:14.6 spid20s进程id = process4fe9048 taskpriority = 0 logused = 0 waitresource = PAGE:46:1:435153 waittime = 14827 ownerId = 421628674 transactionguid = 0x73a1e22f2db893448163a72c7caf84b5 transactionname = user_transaction lasttranstarted = 2019-03-12T16:04:57.190 XDES = 0x8062f2e0 lockMode = U schedulerid = 12 kpid = 10964 status =暂停spid = 96 sbid = 0 ecid = 1 priority = 0 trancount = 0 lastbatchstarted = 2019-03-12T16:04:59.790 lastbatchcompleted = 2019-03-12T16:04:59.780 clientapp = .Net SqlClient数据提供程序hostname = SomeHost hostpid = 470604 isolationlevel =读取已提交(2)xactid = 421628674 currentdb = 46 lockTimeout = 4294967295 clientoption1 = 673185824 clientoption2 = 128056 05:14.6 spid20s executionStack 05:14.6 spid20s frame procname = SOmeDB.dbo.pr_DeleteCLient line = 14 stmtstart = 296 stmtend = 434 sqlhandle = 0x03002e00c33ec3309ab2b800d1a900000100000000000000 05:14.6 spid20s DELETE FROM dbo.Client 05:14.6 spid20s WHERE InvestorCode = @InvestorCode 05:14.6 spid20s inputbuf
死锁通常发生在您想要更新或稍后通过放置共享锁来删除数据时,以下delete
语句无法获取必要的更新锁,因为它们已被不同会话中获取的共享锁阻止造成僵局。
如果它在多个会话中运行,最好使用WITH UPDLOCK
或WITH (SERIALIZABLE)
,如下面的示例
DECLARE @IdToDelete INT
SELECT @IdToDelete =ID FROM [Your_Table] WITH (SERIALIZABLE) WHERE A=B
DELETE [Your_Table]
WHERE ID=@IdToDelete