【问题标题】:Deadlock Problem because of an Update Lock由于更新锁导致的死锁问题
【发布时间】:2010-05-11 20:56:07
【问题描述】:

我们正试图追查一个死锁问题。我有一个从 Profiler 生成的死锁图 (xdl)。它将丢失的 SQL 语句显示为简单的 Select 语句,而不是 Update、Delete 或 Insert 语句。该图将失败的 Select 语句显示为请求资源 **but also owning an Update lock on a resource** 上的共享锁。这让我感到困惑。为什么不属于插入、更新或删除的 Select 语句会在资源上持有更新锁?

我应该补充一点,它拥有的更新锁位于被失败的 Select 语句选择的表上。

编辑:请不要建议使用 NoLock。是的,这将解决问题,但引入了一个新问题——脏读问题。此查询正在访问生产服务器。我真正想知道的是为什么 Select 语句会发出更新锁。

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    你确定 SELECT 拥有 U 锁?

    如您所知,U 和 X 锁(以及可序列化的 S 锁)在 事务 期间而不是语句期间持有。因此,从先前执行的语句中发出写入的事务完全有可能拥有 U 锁。为什么它会拥有一个 U 锁,而不是一个 X 锁(即它拥有一个 U 锁没有升级到 X),这本身就是一个谜,但我可以设想这可能发生的几种方式。
    因此,如果 SELECT 语句是多语句事务的一部分,那么它完全有可能拥有 X/U 锁。一个带有 U 形锁的独立 SELECT,我认为这有点不寻常。

    典型的 SELECT 与 UPDATE 死锁发生在索引访问顺序场景中,例如 Read/Write deadlock 中描述的情况。我相信您对死锁图进行了认真的阅读,但是如果要求不高,您可以分享一下吗?

    哦,顺便说一句,你考虑过读取提交的快照吗?

    【讨论】:

    • 我很乐意分享。我应该怎么做?
    • 如果不能在线分享,发给我。我的电子邮件在我网站上的联系页面上rusanu.com/contact-us
    • 我只是将它发送到您联系页面上的电子邮件地址。
    【解决方案2】:

    select 语句确实会创建共享锁。使用 nolock 提示尝试 select。它会解决问题。

    例如:

    select * from table(nolock)
    

    【讨论】:

    • @Byron - 是的,我知道 Select 创建了一个共享锁。我的问题涉及更新锁。 NoLock 解决了一个问题并引入了另一个问题。它解决了锁定问题并引入了脏读问题。
    【解决方案3】:

    也许选择是使用 UPDLOCK 提示调用的? 无论如何,您可以使用快照隔离并消除问题吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-29
      • 2014-06-15
      • 1970-01-01
      • 1970-01-01
      • 2018-04-20
      • 2012-09-20
      • 2018-06-04
      • 2016-12-22
      相关资源
      最近更新 更多