最近、特定のロック機能が必要なタスクがありました。具体的な原因は次のとおりです。
- テーブルを更新していたトランザクションは分散されていたので制御できませんでしたが、
- 日中、何千ものノンブロッキング トランザクションを同時にサポートする必要があります。それらを「一般的な」操作と呼びましょう。
- 各「一般」操作は、特定の「ブランチ」(「LDN」、「NY」、「LA」...) の行を更新し、
- 1 日に 1 回、各ブランチの「マスター」操作があり、これはさまざまなブランチで頻繁に行われます。
- 「マスター」操作中は、そのブランチで「一般的な」操作を行うことはできません。
- 「マスター」操作が開始されると、「マスター」操作が到着する前にシステムにあった、提供されたブランチ完了で現在の「一般」操作を待機する必要があります。
- 特定のブランチでの「マスター」処理中に、他のすべてのブランチを更新できます。
これをアーカイブするために、Oracle DB固有のテーブルを作成しました
create table BRANCH_LOCK(
BRANCH VARCHAR2(10),
FLAG VARCHAR2(1),
CONSTRAINT "PK_BRANCH_LOCK" PRIMARY KEY ("BRANCH")
)
さまざまな操作に対して次の機能がサポートされました。
「一般的な」操作の場合:
1. In the same XA transaction each operation locks BRANCH_LOCK table in SHARE mode, 2. After locking it checks FLAG, on updated branch, 1. If flag is 'Y', that means that currently 'master' operation is in progess, so Exception is thrown, and no further processing is done; 2. If flag is 'N' than everything is OK, and general processing is done;
「マスター」操作の場合:
- 「マスター」操作が来ると、次の別のトランザクションを開始します。
- BRANCH_LOCK テーブルを EXCLUSIVE モードでロックします。別のトランザクションでこのテーブルに SHARE モード LOCK がある間、トランザクションは取得できません (この方法で、現在のすべての「一般」操作が終了した後に「マスター」操作が開始されることを保証しますが、待機します)指定された支店だけでなく、すべての支店の取引が完了するまで)、
- ブランチのフラグを「Y」に設定します (この方法で、「マスター」操作の処理中に「一般」トランザクションが発生しないことが保証されます)。
- 着信トランザクションで、テーブルのフラグを「N」に変更するため、コミット後、BRANCH_LOG テーブルの FLAG 列に適切な値が含まれ、システムは「一般的な」操作を再び処理できるようになります。
これはまだ製品化されていないので、これに対するより良い解決策があるのではないかと思います。また、説明されているもの以外に欠点はありますか?
私が言及しなかったいくつかの更新:
- 'マスター' 操作は '一般' 操作の結果に作用します. したがって, 'マスター' 処理中に '一般' 操作が失われないことが重要です. したがって, マスター操作が処理を開始する前に現在の '一般' 操作を終了する必要があるのはこのためです. .
- 同じブランチで複数の「一般的な」操作が毎秒発生し、1 秒あたり約 3,000 回の操作が行われます。
- ブランチの「マスター」操作は 1 つだけ実行でき、異なるブランチで複数の「マスター」操作を同時に処理できます。