2011-01-25 25 views
6

Java-Seam-Hibernateアプリケーションから外部のアカウンティング操作を行うためのJAR形式の「API」が与えられました。管理されたトランザクションを手動でコミットする方法

内部的には、APIは、Seam自身から使用された2つの独立したデータソースを使用するプレーンなHibernateアプリケーションです。

問題は内部.commit()を実行するとき、「API」の操作のいずれかが、次の例外を発生させることである:

java.sql.SQLException: You cannot commit during a managed transaction! 
    at org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.jdbcCommit(BaseWrapperManagedConnection.java:543) 
    at org.jboss.resource.adapter.jdbc.WrappedConnection.commit(WrappedConnection.java:334) 
    at org.hibernate.transaction.JDBCTransaction.commitAndResetAutoCommit(JDBCTransaction.java:139) 
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:115) 
    at com.other.APIAccountingImpl.moneyMovement(APIAccountingImpl.java:261) 
    at com.myapp.integration.ExternalApiIntegrator.storeAcountingData(ExternalApiIntegrator.java:125) 
    at com.myapp.session.EmployeeAccounting.persistData(EmployeeAccounting.java:123) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at ... 

moneyMovementメソッドのソースコードは標準Hibernate Session transaction idiom次のようになります。

Session sess = factory.openSession(); 
Transaction tx; 
try { 
    tx = sess.beginTransaction(); 
    //do some work 
    ... 
    tx.commit(); 
} 
catch (Exception e) { 
    if (tx!=null) tx.rollback(); 
    throw e; 
} 
finally { 
    sess.close(); 
} 

私はJTAとSeam管理トランザクションを使用しています。私もカスタムAPIを使用する必要があり、ソースコードを変更することはできません。

私の選択肢には何がありますか?どのようにしてSeam管理トランザクションを "API" Hibernate Sessionから分離できますか?特定のデータソースから管理されたtrxにならないように接続を設定することは可能ですか?

答えて

2

トランザクション管理のJava EE標準であるJTAを使用している可能性があります。この場合、管理対象トランザクションを使用しています。これは、コンテナ(JBoss、それはそうだと思われます)がトランザクションの境界を処理していることを意味し、JTAのセマンティクスを使用してトランザクションをロールバックします。このシナリオでは、トランザクションAPIを直接処理しません。間違いが起こった場合に備えて例外をスローするだけで、トランザクションの他の部分をロールバックすることができます。

あなたが受け取ったこのJARがJTA APIであることを確認することをお勧めします。そうでない場合は、そのドキュメントが必要です。そうであれば、トランザクションAPI(および注釈)を使用して、トランザクションの明示的な境界を使用することができます。 (一部の文書はhttp://download.oracle.com/javaee/5/tutorial/doc/bnciy.html#bnciz

全体として、トランザクションは通常はビジネスメソッドのコンテキスト内で行われるため、コンテナにトランザクションを管理させることをお勧めしますより多くのDAOは、それぞれのDAOメソッドの中にあるトランザクションを超えて存在します。

0

2つのトランザクションをリンクさせたい場合は、トランザクションインスタンスが制御するように、hibernateのコンフィグレーションを実行することができます。したがって、基本的な休止状態コードに何もせず、シームが実際のトランザクションを制御するダミートランザクションを与えることができます。

2つのトランザクションをリンクしたくない場合は、トランザクション属性が「サポートされていません」というejbメソッドからAPIを呼び出すことができます(Seamの仕組みははっきりしませんが、フード)。これにより、現在のSeamトランザクションからAPIトランザクションが分離されます。