首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL死锁图-查找保持锁的确切语句及其启动时间

SQL死锁图-查找保持锁的确切语句及其启动时间
EN

Database Administration用户
提问于 2017-11-10 05:42:35
回答 1查看 1.3K关注 0票数 2

我正在尝试解决一个复杂的死锁问题。

有两个单独的进程(服务和代理作业),它们通常同时执行相同的SP,但具有不同的@BatchID参数。此SP在显式BEGIN TRAN中调用。SP中有30种不同的Insert/Update语句。这两个进程每天在相同的表/索引上死锁5次,每天大约相同的时间,而服务进程始终是受害者。该表有许多不必要的/冗余索引和两个Insert/Update触发器。锁定升级被禁用。

死锁图:

死锁声明:

我们知道幸存者/受害者是SQL会话(SPID),而不是SQL语句。

我们还知道,两个会话的Frame1中显示的UPDATE语句都与死锁有关。他们是怎么参与的?它们都是索引键U锁的请求者。到目前为止我是否正确..。

但是,哪些声明是所有者?他们什么时候开始持有索引键上的X锁的?

解决/减少死锁的标准建议之一是缩短事务。

但是,如果有100条类似的语句,而不知道哪条语句开始持有锁以及何时开始,那么缩短事务是不容易的。

EN

回答 1

Database Administration用户

发布于 2017-11-10 14:25:40

问题1:但是谁是业主呢?

语句没有锁。交易拥有锁。

他们什么时候开始持有索引键上的X锁的?

死锁图或DMVs中没有什么能告诉你这一点。该信息仅在跟踪事件或XEvent中可用,此时获取锁。

是仅在满足UPDATE WHERE子句的行上保持的键锁,还是保存在与索引中的值匹配的所有值上

update使用U锁读取,然后转换为X锁以更新。

它会通过在更新中添加(TABLOCK)而消失吗?

可能吧。解决死锁的一个关键策略是更早更大地锁定。只有当两个会话获得兼容的锁,然后尝试获取不兼容的锁时,才会出现死锁。如果事务中的第一个锁是不兼容的,那么第二个会话将等到第一个提交才获得其第一个锁。

在合适的粒度上获取锁的一个简单方法是使用服务提供商_getapplock来使用应用程序锁。如果您决定事务A和B不能同时运行,那么只需让每个事务在开始时获得相同的应用程序锁,它们就会按顺序运行。

票数 2
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/190613

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档