5

同じデータベースを使用しているコンピューターがいくつかあります(SQL Server 2008)

データベースを使用して、これらすべてのコンピューター間でタスクを同期しようとしています。

各タスクは、ロックIDであるGUIDで表されます(Mutexと比較した場合、Mutex名になります)

私はいくつかの考えを持っていますが、それらは一種のハックであり、ここの誰かがより良い解決策を持っていることを望んでいたと思います:

  1. 新しいテーブルを作成します。各行はGUIDで構成され、テーブルの行をトランザクションで排他的にロックします。終了したら、トランザクションを完了/元に戻します。
  2. sp_getapplockロック名がlock-idguidであるトランザクションでを使用します

トランザクションを実行し続けるのはあまり良くないと思います...オープンなトランザクションやセッションを保持する必要がないソリューションがあるのではないかと思いました。

4

3 に答える 3

0

所有している唯一の共有リソースがデータベースである場合、ソリューションの一部としてトランザクション ロックを使用することが最善の選択肢になる可能性があります。また、他の回答で @Remus Rusanu によってリンクされた記事を理解している場合は、デキューもトランザクションに含める必要があります。

これらのロックを開いたままにしておく予定の期間によって多少異なります。あなたがいる場合...

  1. 問題のロック ID に対する簡単な操作のシリアル化を強制する
  2. とにかくその操作を完了するためにすでにトランザクションを開いています

...その場合、オプション 2 がおそらく最も簡単で信頼性が高いでしょう。私はこのようなソリューションを本番システムで数年間問題なく使用してきました。ミューテックスの作成をトランザクションの作成にバンドルし、すべてを「using」ブロックにラップすると、さらに簡単になります。

using (var transaction = MyTransactionUtil.CreateTransaction(mutexName))
{
    // do stuff
    transaction.Commit();
}

CreateTransaction ユーティリティ メソッドで、トランザクションを作成した直後に sp_getapplock を呼び出します。次に、全体 (ミューテックスを含む) がコミットまたはロールバックされます。

于 2012-09-12T18:29:11.800 に答える
0

むしろ別の方法をお勧めします: queue を使用します。タスクを明示的にロックするのではなく、タスクを処理キューに追加し、キュー ハンドラがタスクをデキューして作業を実行できるようにします。追加のデカップリングは、スケーラビリティとスループットにも役立ちます。

于 2012-08-13T14:45:22.130 に答える