我目前遇到了Server 2008中特定用户表频繁死锁的问题。下面是关于这个表的一些事实:
在检查sys.tables上的表时,我发现lock_escalation被设置为TABLE
我很想把这个表的lock_escalation转换为DISABLE,但我不太确定这会产生什么副作用。据我所知,使用DISABLE将最大限度地减少TABLE级别上不断升级的锁,如果与索引的行锁设置相结合,理论上可以将我遇到的死锁最小化。
从我在确定锁升级的阈值中看到的情况来看,当单个事务获取5000行时,锁定似乎会自动升级。
从这个意义上说,单个事务意味着什么?单个会话/连接通过单个update/select语句获得5000行?
还是单个sql update/select语句获取5000或更多行?
任何见解都很感谢,顺便说一句,这里是n00b DBA。
谢谢
发布于 2012-12-19 06:24:45
当一个语句在单个对象上持有超过5000个锁时,将触发锁升级。在同一表的两个不同索引上,一个包含3000个锁的语句不会触发升级。
当尝试进行锁升级,并且对象上存在冲突锁时,在另一个1250个锁(持有,而不是获得)之后,尝试将被中止并重新尝试。
因此,如果您的更新是对单个行执行的,并且列上有一个支持索引,那么锁升级就不是您的问题了。
您将能够使用探查器中的Locks->锁升级事件来验证这一点。
我建议您捕获死锁跟踪,以确定死锁的实际原因。
发布于 2015-07-08 13:48:44
在Google快速禁用表锁升级之后,我找到了本文。虽然对于OP来说不是一个真正的答案,但我认为它仍然适用于一个不需要的脚本,并且值得注意。有一个很好的小技巧可以用来暂时禁用表锁升级。
打开另一个连接并发出类似的命令。
BEGIN TRAN
SELECT * FROM mytable (UPDLOCK, HOLDLOCK) WHERE 1=0
WAITFOR DELAY '1:00:00'
COMMIT TRAN作为
如果不同的SPID当前持有不兼容的表锁,则无法进行锁升级。
https://stackoverflow.com/questions/13945834
复制相似问题