OracleデータベースでGlassfish3.1.1を実行していますが、トランザクションがロールバックされないという問題が発生しましたが、これまでのところ1つの特定の環境でのみ発生しています。同じアプリケーションが他のマシンで期待どおりに機能します。ただし、同じマシン上の2つの別々のGlassfishドメインが影響を受けます。
影響を受ける環境内では、RuntimeExceptionをスローするEJB内のコンテナー管理トランザクション(CMT)と、を使用したBean管理トランザクション(BMT)の両方で同様の結果が得られUserTransaction#rollback()
ます。
どちらの場合も、根本的な問題は、進行中のJTAトランザクションがある場合でも、JDBC接続がautoCommit=trueで設定されていることであるように見えます。
私のEJB/CMTテストは次のようになります。
@Named
@Stateless
public class TransactionTest {
@PersistenceContext
EntityManager entityManager;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void rollbackTest() {
Foo foo = new Foo();
entityManager.persist(foo);
entityManager.flush();
throw new RuntimeException("should be rolled back");
}
}
私のBMT/UserTransactionテストは次のようになります。
public void rollbackUtxTest() throws Exception {
utx.begin();
Foo foo = new Foo();
entityManager.persist(foo);
entityManager.flush();
utx.rollback();
}
いずれかのメソッドを呼び出すとINSERT INTO FOO
、トランザクションがロールバックされた場合でも、がコミットされます。
何が欠けていますか?接続プールがない/データソースが正しく設定されていない可能性がありますか?
データソースクラス名としてOracleConnectionPoolDataSourceを使用しています。データベース接続がJTAトランザクションに確実に参加するために必要なことはありますか?
UPDATE 1もともとこれは問題だと思ってOracleConnectionPoolDataSource
いましたが、相関関係がないことがわかりました。同じ正確なプール構成が一方の環境で機能しますが、もう一方の環境では機能しません。
UPDATE2これは特にEJB/CMTの問題ではなく、一般的なJTAの問題であることを明確にしました。
UPDATE 3は、JDBC自動コミットに関する情報を追加しました。persistence.xmlが正しいことを確認しました。