私のアプリケーションでは、分散ロックパターンを実行する必要があります。使用する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つあります:
SERIALIZABLE
も行う必要がありますか?SQL Serverは2008/2012のどちらでもかまいません
「ロック解除」
SERIALIZABLE
も行う必要がありますか?
名前にもかかわらず、 シリアライズ可能な分離レベル は、トランザクションが順番に、または受け取った順序で実行されることを保証しません。むしろ、シリアライズ可能な保証トランザクションは、データベースに同じ永続的な影響を及ぼしますifそれらが順次実行された場合未定義の順序(詳細については、リンクを参照してください)。
使用できる他のアプローチ/忘れたものはありますか?
はい。 SQL Serverはすでに次の方法で任意のアプリケーションロックをサポートしています。
これらの組み込みのapplock機能は、幅広いオプションを提供し、自動デッドロック検出を含みます(ただし、必要なトランザクションのロールバックはプログラマーの責任です)。たとえば、さまざまなモードで、トランザクションスコープおよびセッションスコープのロックから選択できます。これらの機能を使用して必要な動作を実装することは非常に簡単で、独自の復元力と信頼性のあるロックマネージャーをゼロから構築するよりも確かに簡単です。