在 SQL Server 中实现应用程序锁(分布式锁定模式)

Stu*_*ler 7 sql-server locking isolation-level

在我的应用程序中,我必须执行分布式锁定模式。因为我们已经有一个 SQL Server 实例可以使用,所以我们决定在我们的 Web 应用程序的 SQL 层实现锁定是最容易的。

可以根据多种条件获得锁,包括:

  • 请求的锁类型
  • 任意应用程序标识符

出于所有意图和目的,将上述两个条件视为int数据类型。

在这种模式中,我们希望将我们所有的锁都视为 FIFO,我相信SERIALIZABLE隔离级别会给我们带来这种好处。

以下是我们建议如何执行“锁定”:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

IF EXISTS (SELECT 1 FROM locks WHERE LockType = @LockType AND ApplicationIdentifier = @ApplicationIdentifier)
    BEGIN
        -- Awesome, the lock will be acquired
        INSERT INTO locks OUTPUT INSERTED.LockId VALUES (2,3)
    END
ELSE
    BEGIN
        -- Someone already has the lock
        SELECT -1
    END

SET TRANSACTION ISOLATION LEVEL READ COMITTED
Run Code Online (Sandbox Code Playgroud)

和“解锁”:

DELETE FROM locks WHERE LockId = @LockId
Run Code Online (Sandbox Code Playgroud)

所以我的问题有两个方面:

  1. 我还需要“解锁”SERIALIZABLE吗?
  2. 有没有我可以使用的其他方法/我忘记的任何东西?

SQL Server 可以是 2008/2012

Pau*_*ite 12

我还需要“解锁”SERIALIZABLE吗?

尽管名称如此,可序列化隔离级别并不能保证事务将按顺序执行,或按接收顺序执行。相反,可序列化保证事务对数据库具有相同的持久效果,就像它们以某种未定义的顺序顺序执行一样(有关更多详细信息,请参阅链接)。

有没有我可以使用的其他方法/我忘记的任何东西?

是的。SQL Server 已经通过以下方式提供了对任意应用程序锁的支持:

这些内置的应用锁功能提供了广泛的选项,包括自动死锁检测(尽管所需的任何事务回滚都是程序员的责任)。例如,您可以在多种模式下从事务范围和会话范围的锁定中进行选择。使用这些特性来实现你需要的行为应该非常简单,而且肯定比从头开始构建你自己的弹性和可靠的锁管理器更简单。