MS SQL 服务器中的隔离级别、锁定模式、死锁和 sp_getapplock

IsolationLevel, Lock Modes, deadlocks and sp_getapplock in MS SQL Server

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

  1. SQL 服务器使用合适的 Lock Mode depending on the IsolationLevel I set while beginning the transaction. If this understanding is correct, what's the purpose of sp_getapplock ?
  2. 我 运行 遇到了 SQL 死锁问题。我的 ASP.NET 应用程序 运行 在不同服务器上的多个实例访问同一个数据库。如果我在事务上使用适当的 IsolationLevel,我还需要使用 sp_getapplock 获取 SQL 锁吗?

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

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

以下是从文章中复制的:

开发人员和 DBA 经常认为他们的 SQL 服务器实例正在经历死锁,而实际上,它正在经历严重的阻塞。

阻塞 当会话 A 请求锁定资源(通常是行、页面或 table),但 SQL 服务器无法授予锁定,因为会话 B 已经持有该资源的不兼容锁。

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

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

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

关于死锁 - 你必须设计你的过程来最小化死锁的可能性,然后你需要创建一些错误处理来检测死锁并采取适当的行动(例如重试 5 次,之后失败)。

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