アプリケーションの設計に問題があります。楽観的ロックも悲観的ロックも解決しない傾向があります。これは、状況を説明する問題の簡略化/変更バージョンです。
問題の前提:
私が達成しようとすること:
データベースに未処理のドキュメントが10個あるとします。最初のクライアントは、未処理のドキュメントの数を要求します。応答は10です。彼はそのうちの6つを要求し、処理を開始します。彼が完了する前に、2番目のクライアントは未処理のドキュメントの数を要求します。彼が最初のクライアントと同じドキュメントを処理する意味がないので、プログラムに「4つの未処理のドキュメントがあります」と答えてほしい。
これらの6つのドキュメントを楽観的にロックした場合の問題:
このアプリケーショントランザクションの特定のケースでは、長い時間がかかり、他のクライアントがまだ4つではなく10個の未処理のドキュメントがあると考える大きな可能性があります。
これらの6つのドキュメントを悲観的にロックした場合の問題:
繰り返しになりますが、トランザクションは完了するまでに長い時間がかかり、他のクライアントはドキュメントの数についての回答を待って行き詰まります。
トランザクションを短縮し、処理前にステータス変更をコミットする場合の問題:
停電が発生する可能性があります。その結果、6つのドキュメントのステータスが「処理のためにエクスポートされました」ですが、実際にはそうではありません。
同時アクセスと長いトランザクションがあるこの種のシナリオでは、どのような代替/カスタムロック戦略を選択する必要がありますか?
私は(少なくとも)4つのドキュメント状態でこれを解決しようとします
さらに、最後の状態がいつ変更されたかを記憶するためにタイムスタンプフィールドを追加し、@ Bartが指摘したように、ユーザーが状態変更を引き起こした追加のフィールドを追加することはおそらく良い考えでしょう。
状態の変更自体は、ドキュメントごとに、単一の短いアトミックトランザクションで行う必要があります。たとえば、エクスポートを開始する前に、状態を適切に設定します。エクスポートが正常に完了したら、それに応じて状態も設定します。文書が処理されたとき。これにより、トランザクションをきめ細かく制御でき、個々の障害回復が可能になります。
たとえば、100個のドキュメントのエクスポートの途中で停電またはネットワーク障害が発生した場合、約50のドキュメントが「エクスポート開始済み」、50のドキュメントが「処理中」になります。タイムスタンプフィールドを使用すると、状態がまだ「エクスポート開始」、たとえば15分を超えているドキュメントがある場合に簡単に検出し、このタイムアウト後にそれらのドキュメントを「未処理」にリセットできます。処理に5日以上かかる場合は、ドキュメントを「処理中」から未処理にリセットすることもできます。これらの保留状態のチェックは、別のバックグラウンドプログラムで実行できます。たとえば、毎分、または5分ごとに、プロセスに最適なものを実行します。
実際、「これらのドキュメントのロック」とは、「未処理」とは異なる状態のすべてのドキュメントが他からのエクスポートおよび処理のためにロックされていることを意味します。ただし、長期的な「データベースロックメカニズム」を使用してはロックされません。データベースは常に応答性を維持し、どの状態のドキュメントがいくつ保存されているかを通知します。私の理解では、これはまだ「悲観的ロック」戦略と呼ばれます(同じドキュメントが2人の異なるユーザーによって同時に処理されないため)が、フェイルオーバー戦略を伴います。
「ロック」には、純粋な悲観的(「このドキュメントが見られている間は他のアクセスを許可しないでください!」)と純粋な楽観的(「このドキュメントへのアクセスまたは更新が競合しないことを前提としています」)よりも多くの段階があります。お互いに!」)。
より細かく、依然として悲観的なロックがあります。たとえば、クライアントが一度に1つのドキュメントしか取り出せないようにします。これは、DBMS設計の「テーブルロック」ではなく「行レベルロック」に似ています。
マルチバージョン同時実行制御 は、最も悲観的なロックの仮定の代わりに、最新のデータベースマネージャーが使用するものです。従来の悲観的ロックと同じ [〜#〜] acid [〜#〜] プロパティを提供できます。
同時リアルタイムエディター GoogleドキュメントやEtherPadと同様に、複数のクライアントから一貫したドキュメントモデルへの複数の同時更新が可能です。メリットとデメリットのどちらも、「チェックアウト」機能がないことであり、論理的/意味論的な調整はクライアントの責任です。
分散リビジョン管理システム GitやMercurialのように非常に楽観的で寛容な見方:誰もが必要なすべてのドキュメントのコピーを取得し、必要な変更を加えることができます。後でそれらの変更をコミットしたい場合、すべての変更をマスターに正常にマージ/再統合できることが前提です(完全な自動化でそれを実行できない場合は、ハード競合を自動的に識別して提示できる)整理のために人間に)。
しかし、ロック戦略ではなく、 分散ジョブスケジューラ が必要なようです。太古の昔から今日に至るまでのすべてのHPC環境には、ジョブが終了したときやAWOLになったときのエラー処理など、何らかの形式のジョブスケジューリングがあります。したがって、ドキュメントロックを自分で管理するための代替戦略に加えて、この機能をジョブマネージャーに簡単にアウトソーシングできるかどうかを検討してください。