2011-11-15 7 views
2

私はマルチスレッドで動作するHibernateトランザクションメソッド "doImportImpl"を持っています。また、レコード識別子を持ち、レコードのインポートと並列に実行することはできません別の取引方法がありメソッドの周りに定義されたJavaのアスペクトをどのように同期できますか?

public RecordResult doImportImpl(String data) { 
    RecordResult result = new RecordResult(); 
    .. do some data processing .. 
    String recordIdentifier = getIdentifier(data); 
    synchronized(recordIdentifier) { 
     process record; 
    } 
    return result; 
} 

:コードの構造は大体このようなものですので、特定のレコードは、しかし、順番にインポートする必要があります。したがって、 'レコード識別子'にも同期されます。ここで

public void autoProcess(String data) { 
    String recordIdentifier = getIdentifier(data); 
    synchronized(recordIdentifier) { 
     List<Record> records = dao.queryDatabase(recordIdentifier); 
     for (Record r : records) { 
      autoprocess record; 
     } 
    } 
} 

は問題だ:時々doImportImpl()から同期ブロックの後に実行を開始autoProcess()メソッドが終了されますが、トランザクションがコミットされる前に、そのようです。したがって、tx分離レベルのため、dao.queryDatabase()への呼び出しでは、インポートされたレコードがデータベースにまだ表示されません。

メソッド呼び出し(Hibernateトランザクション管理を処理する)に関するすべての側面を含む "return文"を通じて、同期ロックが確実に保持されるようにするにはどうすればよいですか? return文をsynchronizedブロックに入れるだけで十分ですか?

おかげ サイモンNiederberger

答えて

0

あなたは、データベースロックの代わりに、​​ブロックを使用する必要があります。 recordIdentifierでレコードを照会するときは、select for updateまたはデータベースで使用可能なものを使用します。

また、私にとってはStringで同期するような匂いがします。

+0

ヒントをお願いします。文字列の同期。私はその意味を理解していると思っていましたが、その話題についてもう少し詳しく読んだら間違っていることが判明しました。私はその部分を変更するつもりですが、主な質問はまだありません。私は「更新を選択」するのは嫌です。DBのパフォーマンスにかなり影響するためです。 98%の時間は同じレコード識別子を持つデータの同時処理がないため、コードはそのケースに対して最適化する必要があります。 – Simon

+0

その後、オプティミスティック・ロックを使用します。 – kan

関連する問題