【问题标题】:How to get rid of the deadlock如何摆脱僵局
【发布时间】:2012-11-13 09:06:41
【问题描述】:

我在这里描述了这个问题: Deadlock under ReadCommited IL 并得到了答案:

So a deadlock can occur when running SELECTs because the transaction running 
those selects had acquired write locks before running the SELECT.

好的,那我该怎么做才能摆脱它?有一些常见类型的死锁可以通过添加覆盖索引或更改隔离级别(更改 sql 命令文本、使用表提示等)来解决,但我想不出适合我的情况的解决方案。

似乎这是最常见和最简单的死锁原因:

  1. 进程 A 获得资源 R1 的锁定,进程 B 获得资源 R2 的锁定
  2. 进程A等待资源R2被释放,进程B等待R1

所以这在很大程度上是一个并行问题,而且很可能也是业务逻辑。

如果将锁应用于行,也许我可以避免死锁,但似乎一个页面中有几个行锁,然后发生锁升级,然后我锁定了整个页面。

你有什么建议?禁用锁升级?我可以在本地进行 1 次交易吗? 或者也许应用一些表格提示(WITH ROWLOCK)或其他东西......idk

现在不能将隔离级别更改为快照(或其他类型)。 谢谢。

【问题讨论】:

  • “现在不能将隔离级别更改为快照(或其他类型)” - 您能解释一下原因吗?
  • 死锁是正常数据库操作的一部分。大多数情况下,当发生死锁时,SQL Server 错误实际上会告诉您重试死锁牺牲品。这就是你应该做的。
  • @MitchWheat,我不知道为什么,但我不能在没有适当调查的情况下更改系统中的默认 IL。我研究了 Snapshot IL 和 RCS,据我所知,这些可能会导致 DB 中的数据不正确或不一致(虽然是的 - 我会摆脱死锁)

标签: sql-server transactions parallel-processing deadlock


【解决方案1】:

修复死锁主要是特定于正在考虑的特定事务的任务。几乎没有给出一般性建议(除了启用快照隔离,这是您无法做到的)。

一种模式作为标准修复出现了,但是:使用正确的锁定模式以正确的顺序获取所有必要的锁定。这可能意味着选择 WITH (UPDLOCK, ROWLOCK, HOLDLOCK) 以主动 U 形锁定行。

我没有看到锁升级是问题,因为它需要非常多的锁才能启动。当然这可能是原因,但大多数情况下,行锁足以触发死锁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 2022-01-21
    • 2014-01-28
    • 2013-10-31
    • 2020-10-19
    相关资源
    最近更新 更多