2013-06-26 39 views
2

我正在實現一個EJB應用程序。在這一點上,我需要一個交易。我需要在行中執行3個方法,如果一個失敗,所有的東西都應該回滾。 這裏:http://www.conceptgo.com/gsejb/eb04.html,我找到了一個教程。 我的代碼:在EJB中使用javax.transaction.UserTransaction實現事務

try { 
     javax.transaction.UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction"); 
     ut.begin(); 
     Feeds feed = loadFeed(url); 

     try{ 
      em.persist(feed); 
      uf.setFeedId(feed.getFeedId()); 
      uf.setUserId(user_id);   
      em.persist(uf); 
     }catch (EntityExistsException e){ 
      ut.rollback(); 
      return false; 
     }catch (IllegalArgumentException ea){ 
      ut.rollback(); 
      return false; 
     } 
     if (feed.getFeedId()!= null && feed!=null) { 
      ut.commit(); 
     }else{ 
      ut.rollback(); 
      return false; 
     } 

當我運行我的應用程序,我得到一個錯誤信息:

Caused by: java.lang.IllegalStateException: BaseTransaction.checkTransactionState 
- ARJUNA016051: thread is already associated with a transaction 

任何人都知道什麼原因,如何解決呢?

回答

5

該錯誤意味着您已經有一個正在進行的交易,很可能是一個容器管理的交易。

你的bean /方法是什麼樣的? JBoss7中無狀態會話bean的默認事務行爲是使用Container管理事務和「必需」事務屬性來執行。

因此,假設容器管理事務爲您工作,您不需要UserTransaction。所以你可以刪除查找和開始/提交/回滾,因爲這將爲你管理。

如果您確實想自己管理事務,那麼將bean標記爲使用Bean託管事務,然後您可以開始/提交/回滾UserTransaction。要將bean標記爲使用bean管理的事務,您將將註釋@TransactionManagement(TransactionManagementType.BEAN)應用於類或方法。

+0

你好。感謝您的答覆。聽起來不錯。但是,我覺得我所做的命令並不相互關聯。不知道爲什麼ejb會執行交易fior不相關的東西?首先我堅持Feed類對象,然後是UserFeed類型對象。 em.persist(飼料); uf.setFeedId(feed.getFeedId()); uf.setUserId(user_id); em.persist(uf); – Sermilion

+0

好的,如果您確實需要自己管理事務,則需要聲明您的bean將自己管理事務,然後使用UserTransactions。我已經在上面更新了我的答案。 – Raylite3

2

由於錯誤顯示您嘗試中斷JBoss中的容器管理事務。如果你想用自己的方式處理事務,那就改變你的類/方法bean的管理方式。

@TransactionManagement(TransactionManagementType.BEAN) 
public void getTransaction(){ 
    //.... 
} 

現在你是來自JBoss的最終安全的,但保證你必須定義在豆交易的每一步管理的事務。

+0

非常感謝。這種情況下,有沒有辦法管理一些方法與容器管理和一些在userTransactions。或者是否意味着bean中的每個方法都將被託管userTransaction? – Sermilion

+2

'@ TransactionManagement'有'@Target(ElementType.TYPE)',所以你不能使用它註釋方法 - 只有類/接口/ .... – rzymek

1

CMT容器將負責處理事務和相關的線程,因此建議不要使用CMT的幾個步驟和BMT的幾個步驟。因此,ejb容器將獲得對參與交易的對象的鎖定,並且只有在交易完成時這些對象纔會被釋放,否則這些對象可能會導致問題,如果您在BMT中需要它。所以你必須使用CMT或BMT。

+0

謝謝。但是,有時當我使用persist()這樣簡單的方法時,如果我使用的是BMT,則會引發錯誤,即Transaction Required。在這種情況下做什麼? – Sermilion

+1

這意味着您在方法()中使用了事務,但您的操作不在事務中。只需使用@TransactionAttribute(TransactionAttributeType.Required)public void createDepartment(){} – 2013-11-25 16:36:14