0

それが私の要件です。データベース レコードをロックし、処理して解放することです。

環境 - weblogic 10.3 データベース - Oracle 11g データソース - 複数の XA リソースが関与 Tx マネージャー - JTA

これまでに行った実験の結果は次のとおりです。

実験 1 - コミットされていない読み取りに依存する

  1. データベースレコードを読む
  2. グローバル JTA トランザクションの一部として、別のテーブルの ID でレコードをロックします。
  3. レコードを処理する 同じレコードをロックしようとする 2 番目のトランザクションは失敗し、レコードをドロップします。ただし、これが機能するには、RDBMS でダーティ リードが許可されている必要があります。残念ながら、Oracle はコミットされていない読み取り分離レベルをサポートしていません。

実験 2 - ローカル トランザクションでレコードをロックする

  1. データベースレコードを読む
  2. 別のローカル トランザクションとして、別のテーブルの ID でレコードをロックします。
  3. レコードを処理し、トランザクションが正常にコミットされたらレコードを削除します。同じレコードをロックしようとする 2 番目のトランザクションは失敗し、レコードが削除されます。このアプローチはコミットされたデータに基づいており、うまく機能するはずです。ここに問題があります - ロック トランザクションとグローバル親が異なるため、処理がメイン トランザクションのロールバックに失敗した場合、ロック トランザクションをロールバックすることで補償する必要がありますが、これを行う方法がわかりません -ここで助けが必要です

レコード ロック トランザクションをロールバックできない場合は、レコード ロック コードの周りにダーティ ロジックを記述する必要があります。私はこれを好みません。

これは非常に一般的な要件のようです。皆さんがこれをエレガントに処理する方法を知りたいです。オラクルは、コミットされていない更新をすべてのトランザクションに可視化することを何らかの方法でサポートしていますか?

よろしくお願いします。

4

1 に答える 1

1

実験2で説明したものを大まかに実装するユーティリティクラスがあります。

前提条件: ロック専用のテーブルがあること

ロック フェーズでは、新しい接続が作成されます。INSERT INTO がロック テーブルに対して実行されます。

ロック解除フェーズでは、ビジネス ロジックの実行に関係なく、接続のロールバックが実行されます。

java.util.concurrent.locks.Lock のように使用されます。

Lock lock = new Lock(...);
lock.lock();
try {

    // your business logic
} finally {
   lock.unlock();
}

Websphere / Oracle で動作します。

JPA を使用する場合は、エンティティ ロックのサポートが組み込まれていることに注意してください。

于 2011-09-12T16:40:36.530 に答える