5

2番目のトランザクションの例外が古いトランザクションではなく新しいトランザクションのみをロールバックするように、進行中のトランザクション内で新しいトランザクションを開始する必要があります。

これは、次のように2番目のトランザクションで伝播属性を設定することで行っています:

@トランザクション (伝播 = 伝播.REQUIRES_NEW)

これにより新しいトランザクションが作成されましたが、新しいトランザクションは最初のトランザクションのコミットされていないデータを読み取り (ダーティ読み取り)、そのデータも更新する必要があります。これは、分離属性を次のように設定して実行しようとしています。

@Transactional(propagation = Propagation.REQUIRES_NEW, isolation=Isolation.READ_UNCOMMITTED)

これにより、例外 - InvalidIsolationLevelException がスローされ、「標準 JPA はカスタム分離レベルをサポートしていません - JPA 実装には特別な JpaDialect を使用してください」というメッセージが表示されます。

JpaDialect の実装に役立つものはありますか? Eclipse Link 2.5.1 を使用しています。

または、新しいトランザクションを開始する前に、最初のトランザクションをどのように閉じることができますか? 最初のトランザクションは閉じられているため、2 番目のトランザクションは、最初のトランザクションによってコミットされたデータを問題なく読み取ることができます。

4

1 に答える 1

1
  • JPAでは、このようなことを試すことができますが、EclipseLink/Springで同様のことを達成する方法についてはあまり確信が持てません。

    ただし、全体的な概念は同じままで、基礎となるデータベース接続を取得し、適切な分離レベルを設定します。

    java.sql.Connection connection = entityManager.unwrap(java.sql.Connection.class);
    connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED); 
    //-- Or with some other constant something like Isolation.READ_UNCOMMITTED
    

    その後、分離レベルをデフォルトにリセットすることもできます。

  • 変更を加えたくない場合は、JpaDialectオーバーライド メソッドを実装して、トランザクションの分離レベルの変更に対応する必要がある場合があります。

    Hibernate の実装について説明しているhereを参照できます。EclipseLink についても同様のことを試すことができます。

于 2015-02-05T13:04:53.523 に答える