2011-01-25 53 views
6

我被給了一個JAR形式的「API」來從我的Java-Seam-Hibernate應用程序中執行一些外部計帳操作。如何手動提交管理的事務

在內部,API是一個普通的Hibernate應用程序,使用兩個獨立的數據源,除了Seam本身使用的數據源。

的問題是,「API」操作中的一個操作的方式的內部.commit()時引發以下例外:

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(); 
} 

我使用Seam與JTA進行管理事務。我也被迫使用自定義API,我不允許修改源代碼。

我的替代品是什麼?如何將Seam管理事務從「API」Hibernate會話中分離出來?可以將特定數據源的連接配置爲不受託管的trx?

回答

2

您可能正在使用JTA,這是用於事務管理的Java EE標準。在這種情況下,您正在使用託管交易。這意味着容器(JBoss,看起來)正在處理事務邊界,並且會在拋出一些異常的情況下使用JTA語義來回滾事務。在這種情況下,您不直接處理事務API。如果發生錯誤,您只需拋出一些異常,並且會負責回滾事務的其他部分。

也就是說,我建議您確認您收到的這個JAR是JTA API。如果不是,那麼你肯定需要它的文檔。如果是這樣,您可以使用事務API(和註釋)來使用明確的事務劃分。 (有些文檔可以在這裏找到:http://download.oracle.com/javaee/5/tutorial/doc/bnciy.html#bnciz

總的來說,我認爲讓容器管理你的事務通常是一個好主意,因爲事務通常是在業務方法的上下文中,這可能涉及兩個或因此,更多的DAO調用存在於每個DAO方法內部的事務之外。

0

如果您希望將2個事務鏈接起來,可能會使用hibernate配置來讓事務實例成爲您控制的實例。因此你可以給底層的hibernate代碼一個虛擬的事務,它什麼都不做,讓seam控制真正的事務。或者,如果您不希望這兩個事務鏈接在一起,那麼您可以使用事務屬性「不支持」的ejb方法調用API(Seam的工作方式不是很清楚,但假設它是ejb罩)。這會將API事務從當前的Seam事務中分離出來。