1

よくある問題のようですが、それに対する簡単な答えはわかりません-

環境

  • Java EE 環境 (複数の JVM)
  • 2 フェーズ コミットのセットアップ
  • オラクルDB

与えられた

「AMOUNT」列を持つ DB テーブル

論理

if SELECT SUM(AMOUNT) WHERE... + current amount < Const. ==> insert row

問題

競合状態 - 「コミット」する場合にのみ行を挿入したいと考えています。その間、他のスレッドが合計に使用したデータにアクセスしたくありません。また、他のスレッドを拘束しないように、アクセスされていないデータベース データをできるだけ減らしたいと考えています。

現在のソリューション

Oracle の SELECT FOR UPDATE メカニズムの使用


この問題に対処するための他の解決策はありますか? すぐに使えるソリューションも歓迎されます。

4

2 に答える 2

0

Oracle では、INSERT WHEN節 (こちらを参照) を使用して、データベースで条件付き挿入を一気に実行できる場合があります (ストレート JDBC を使用):

insert 
  when sumamount + ? < ? then
     into mytable (id, amount, otherfield) values(myseq.nextval, ?, ?)
  select sum(amount) sumamount from mytable

パラメータを使用して:

  • 新しい金額
  • 絶え間ない
  • 新しい金額
  • その他のフィールド値

それがうまくいかない場合は、「シリアル化可能な」分離レベルのトランザクションマネージャーを使用して、ダーティ、ファントム、または反復不可能な読み取りを防ぎます。

于 2012-04-16T09:40:34.057 に答える
0

Java EE の一部としての JPA は、ロック メカニズムを提供します。

一般に、悲観的ロックと楽観的ロックがあります。

実際、悲観的ロックは、データが読み取られるときにテーブルの行をロックします (結果の SQL はSELECT FOR UPDATE ...現在のソリューションと同じです)。

Person person = em.find(Person.class, personPK, LockModeType.PESSIMISTIC_WRITE);

楽観的ロックは、各テーブルのバージョン列を使用します。

public class Employee {
@ID int id;
@Version int version;
...

悲観的なアプローチは、あなたの場合に最も適しているようです

于 2012-04-16T09:41:26.303 に答える