3

我正在实现一个 EJB 应用程序。在这一点上,我需要一笔交易。我需要连续执行 3 个方法,如果一个方法失败,所有内容都应该回滚。在这里: http: //www.conceptgo.com/gsejb/eb04.html,我找到了一个教程。我的代码:

    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

有谁知道是什么原因以及如何解决?

4

3 回答 3

5

该错误意味着您已经有一个正在进行的事务,很可能是一个容器管理的事务。

你的 bean/方法是什么样的?JBoss7 中无状态会话 bean 的默认事务行为是使用容器管理的事务和“必需”事务属性执行。

因此,假设容器管理的事务为您工作,您不需要 UserTransaction。因此,您可以删除查找和开始/提交/回滚,因为这将为您管理。

如果您确实想自己管理事务,则将 bean 标记为使用 Bean 管理的事务,然后您可以开始/提交/回滚 UserTransaction。要将 bean 标记为使用 bean 管理的事务,您将注释 @TransactionManagement(TransactionManagementType.BEAN) 应用于类或方法。

于 2013-06-27T19:51:25.590 回答
2

如错误所示,您正在尝试中断 JBoss 中的容器管理事务。如果您想以自己的方式处理事务,请更改您的类/方法 bean 管理方式。

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

现在您可以从 JBoss 结束,但确保您必须在 Bean 管理的事务中定义事务的每个步骤。

于 2013-07-01T17:17:19.027 回答
1

不建议对 CMT 使用少量步骤,对 BMT 使用少量步骤,因为万一 CMT 容器将负责处理事务和相关线程。因此,ejb 容器将获取参与事务的对象的锁定,并且在事务完成之前不会释放这些对象,如果您在 BMT 中需要它,这些对象可能会导致问题。因此,您必须使用 CMT 或 BMT 。

于 2013-07-01T18:43:55.547 回答