2011-07-07 8 views
6

JPAトランザクション分離レベルでの私の問題について説明しようとします。表1にFK トランザクション分離レベル

JPA(分離レベル:: read_commited)と> -

  • Table1 - > PKと日付( 'DDMMYYYY')として定義
  • Table2

    データベース構造 - コード:

    Query query = em.createQuery("from Table1 trd where trd.id = :d"); 
        query.setParameter("d", date); 
    
        Table1 t = null; 
        try{ 
         t = (Table1) query.getSingleResult(); 
        }catch(javax.persistence.NoResultException e){ 
         t = null; 
        } 
    
        if(t==null){ 
         t=new Table1 (date); 
         em.persist(trd); 
        } 
    
        for(Table2 q:tables2){ 
         q.setTable1(t); 
         em.merge(q); 
        } 
    

    したがって、レコードがdbに存在するかどうかをチェックし、レコードが存在しない場合は新しいレコードを作成します。システムがただ1つのスレッドに基づいている場合、メソッドは完全にcorectです。

    • スレッド1:それ以外の場合、このような可能な状況があるエンティティは、日付がデータベースに存在することで表現するかどうかをチェックし
    • スレッド2:DOがまったく同じ

    それらの両方は、このような記録があると思いまだ存在しないので、新しいものを追加してください。取引をコミットする瞬間まではすべてが大丈夫です。最初のものは例外なくコミットされ、プライマリキーの重複に関連する2番目の1つの例外例外を購入します。

    隔離レベルをSERIALIZABLEに変更する以外は、このような状況を維持する可能性はありますか?

答えて

3

はい、通常は分離レベル= SERIALIZABLEで問題を解決できます。隔離レベルを最も厳格なオプションに変更するときの副作用を過小評価しないでください。これは、データベースの使用率と要求スループットに影響する可能性があります。 TRXを明示的にコミットしてから、別のTRXを開くこともできます。

1

これは、並行性の高い環境でデータベースを使用して解決するのが最も困難な問題の1つです。結局のところ、あなたの唯一の解決策は、例外を捕らえて適切に処理することです。

あなたが提供したコードに基づいて、それが何であるかは分かりません。これがWebアプリケーションの場合は、重複したキーの例外をキャッチして、エンドユーザーに有用なメッセージを表示したいと思う可能性があります。 "このレコードは既に作成されています"などのようなものです。

関連する問題