【问题标题】:IsolationLevel, Lock Modes, deadlocks and sp_getapplock in MS SQL ServerMS SQL Server 中的 IsolationLevel、锁定模式、死锁和 sp_getapplock
【发布时间】:2023-04-02 13:43:01
【问题描述】:

我是 SQL Server 的新手,遇到类似死锁的问题。我读过有关它的文章。我想了解以下内容:

  1. SQL 服务器根据我在开始事务时设置的IsolationLevel 使用适当的Lock Mode。如果这个理解是正确的,那么sp_getapplock的目的是什么?
  2. 我遇到了 SQL 死锁问题。在不同服务器上运行的多个 ASP.NET 应用程序实例访问同一个数据库。如果我对事务使用适当的 IsolationLevel,是否还需要使用 sp_getapplock 获取 SQL 锁?

(我知道更合适的解决方案是识别有问题的交易并修复它们。但这仍然是一个理论问题。)

【问题讨论】:

    标签: sql-server database isolation-level database-deadlocks transaction-isolation


    【解决方案1】:

    阻塞和死锁是两个不同的东西。请阅读this article了解更多详情。

    以下内容抄自文章:

    开发人员和 DBA 经常认为他们的 SQL Server 实例遇到了死锁,而实际上,它遇到了严重的阻塞。

    阻塞发生在会话 A 请求对某个资源(通常是行、页或表)的锁定,但 SQL Server 无法授予该锁定,因为会话 B 已经在该资源上持有不兼容的锁定资源。

    这是一种暂时的情况,可以通过会话 B 完成其工作并释放其锁来完全解决。可能有广泛的阻塞链,其中多个会话被阻塞,等待一个本身被阻塞的会话等待另一个被阻塞的会话,依此类推,重复多次。然而,在阻塞链的头部将是一个不等待锁的头部“阻塞器”。它可能正在等待其他一些资源,例如锁存器、内存或 IO,但至少有一个会话不会等待锁,并且一旦头部阻塞器可以继续处理,阻塞链就会清除。

    死锁是不同的;它发生在两个或多个会话彼此等待时,以一种无法完成的方式。死锁可以看作是一个循环锁链,阻塞链中的每个进程都在等待同一阻塞链中的一个或多个其他进程。

    【讨论】:

      【解决方案2】:

      sp_getapplock 与您的问题没有直接关系。 Applock 是自定义定义的锁,由您的应用程序使用 - 例如,当您需要与外部数据源同步时,使用一些冗长而复杂的过程,并且您不希望多个进程同时运行此类过程。

      关于死锁 - 您必须设计您的程序以最大限度地减少死锁的可能性,然后您需要创建一些错误处理来检测死锁并采取适当的措施(例如重试 5 次,然后失败)。

      如果您可以发布您的死锁过程代码,那么很可能有人可以帮助您重新设计它。

      【讨论】:

      • 感谢您的回答。数据库是如此庞大和复杂,以至于检测导致死锁的资源本身就是一个挑战。无论如何,我都要求提供死锁图。
      • 我是我的旧代码,通常问题在下一个连续:begin tran; select xxxx; update xxxx; commit - 如果 xxxx 包含相同的选择和更新记录,那么死锁很快就会出现。如果您将with(updlock) 提示添加到您的selectstatement,许多(不是全部)问题都会消失。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-03
      相关资源
      最近更新 更多