web-dev-qa-db-ja.com

SQL Server内でのアプリケーションロックの実装(分散ロックパターン)

私のアプリケーションでは、分散ロックパターンを実行する必要があります。使用するSQL Serverのインスタンスが既にあるため、WebアプリケーションのSQLレイヤーでロックを実装するのが最も簡単であると判断しました。

ロックは、次のような多くの条件に基づいて取得できます。

  • 要求されたロックのタイプ
  • 任意のアプリケーション識別子

すべての意図と目的のために、上記の2つの条件を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

そして「アンロック」:

DELETE FROM locks WHERE LockId = @LockId

だから私の質問は2つあります:

  1. "ロック解除" SERIALIZABLEも行う必要がありますか?
  2. 私が使用できる他のアプローチ/私が忘れたものはありますか?

SQL Serverは2008/2012のどちらでもかまいません

7
Stuart Blackler

「ロック解除」SERIALIZABLEも行う必要がありますか?

名前にもかかわらず、 シリアライズ可能な分離レベル は、トランザクションが順番に、または受け取った順序で実行されることを保証しません。むしろ、シリアライズ可能な保証トランザクションは、データベースに同じ永続的な影響を及ぼしますifそれらが順次実行された場合未定義の順序(詳細については、リンクを参照してください)。

使用できる他のアプローチ/忘れたものはありますか?

はい。 SQL Serverはすでに次の方法で任意のアプリケーションロックをサポートしています。

これらの組み込みのapplock機能は、幅広いオプションを提供し、自動デッドロック検出を含みます(ただし、必要なトランザクションのロールバックはプログラマーの責任です)。たとえば、さまざまなモードで、トランザクションスコープおよびセッションスコープのロックから選択できます。これらの機能を使用して必要な動作を実装することは非常に簡単で、独自の復元力と信頼性のあるロックマネージャーをゼロから構築するよりも確かに簡単です。

12
Paul White 9