2

最近、特定のロック機能が必要なタスクがありました。具体的な原因は次のとおりです。

  1. テーブルを更新していたトランザクションは分散されていたので制御できませんでしたが、
  2. 日中、何千ものノンブロッキング トランザクションを同時にサポートする必要があります。それらを「一般的な」操作と呼びましょう。
  3. 各「一般」操作は、特定の「ブランチ」(「LDN」、「NY」、「LA」...) の行を更新し、
  4. 1 日に 1 回、各ブランチの「マスター」操作があり、これはさまざまなブランチで頻繁に行われます。
    1. 「マスター」操作中は、そのブランチで「一般的な」操作を行うことはできません。
    2. 「マスター」操作が開始されると、「マスター」操作が到着する前にシステムにあった、提供されたブランチ完了で現在の「一般」操作を待機する必要があります。
    3. 特定のブランチでの「マスター」処理中に、他のすべてのブランチを更新できます。

これをアーカイブするために、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;

「マスター」操作の場合:

  1. 「マスター」操作が来ると、次の別のトランザクションを開始します。
    1. BRANCH_LOCK テーブルを EXCLUSIVE モードでロックします。別のトランザクションでこのテーブルに SHARE モード LOCK がある間、トランザクションは取得できません (この方法で、現在のすべての「一般」操作が終了した後に「マスター」操作が開始されることを保証しますが、待機します)指定された支店だけでなく、すべての支店の取引が完了するまで)、
    2. ブランチのフラグを「Y」に設定します (この方法で、「マスター」操作の処理中に「一般」トランザクションが発生しないことが保証されます)。
  2. 着信トランザクションで、テーブルのフラグを「N」に変更するため、コミット後、BRANCH_LOG テーブルの FLAG 列に適切な値が含まれ、システムは「一般的な」操作を再び処理できるようになります。

これはまだ製品化されていないので、これに対するより良い解決策があるのではないかと思います。また、説明されているもの以外に欠点はありますか?

私が言及しなかったいくつかの更新:

  1. 'マスター' 操作は '一般' 操作の結果に作用します. したがって, 'マスター' 処理中に '一般' 操作が失われないことが重要です. したがって, マスター操作が処理を開始する前に現在の '一般' 操作を終了する必要があるのはこのためです. .
  2. 同じブランチで複数の「一般的な」操作が毎秒発生し、1 秒あたり約 3,000 回の操作が行われます。
  3. ブランチの「マスター」操作は 1 つだけ実行でき、異なるブランチで複数の「マスター」操作を同時に処理できます。
4

3 に答える 3

2

独自のロックテーブルを作成するのではなく、OracleのロックパッケージDBMS_LOCKを使用しようと思います。

これは、DMLを使用してロックを実行するよりも効率的であり、Oracleが内部でエンキューロックを実行するために使用するものです。

于 2011-02-02T16:29:14.203 に答える
2

アントン、テーブルを手動でロックする必要があるのはなぜですか? 通常はその必要はありません。説明したマスター操作が開始されると、そのマスタートランザクションの開始時にコミットされたデータの読み取り一貫性のあるビューが取得されます。一般的なトランザクションは引き続き機能し、説明したマスター トランザクションは、新しいトランザクションを開始するまで変更を認識しません。

于 2011-02-02T12:30:08.957 に答える
0

テーブル ボリュームとは何ですか。

マスター操作を次のように開始することを検討します

CREATE OR REPLACE PROCEDURE do_master (in_branch IN VARCHAR2) IS
BEGIN
  SELECT ...
  BULK COLLECT INTO
  FROM ...
  WHERE branch = in_branch
  FOR UPDATE OF branch;
  ...
END do_master;

これは、標準の Oracle ロックを使用して、これらのブランチをロックしている未処理の一般的なトランザクションが完了するまで do_master が確実に待機するようにし、その後 do_master によってロックが取得され、コミットされるまで他の一般的な更新を停止します。その後、それらの一般的な更新が再開されます。

しかし、ボリュームが大きい場合、その SELECT...FOR UPDATE は非常に大きくなる可能性があります。それが私が DBMS_LOCK ソリューションを検討するときです。

于 2011-02-02T23:40:54.867 に答える