使用javax.transaction.UserTransaction在EJB中实现事务

时间:2013-06-26 18:59:47

标签: jboss transactions ejb-3.0

我正在实现一个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

任何人都知道原因是什么以及如何解决?

3 个答案:

答案 0 :(得分:5)

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

你的bean /方法是什么样的? JBoss7中无状态会话bean的默认事务行为是它使用Container托管事务和“Required”事务属性执行。

因此,假设容器管理的事务适合您,则不需要UserTransaction。因此,您可以删除查找和begin / commit / rollback,因为这将为您管理。

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

答案 1 :(得分:2)

由于错误显示您正在尝试中断JBoss中的容器管理事务。如果你想用自己的方式处理事务,那么改变你的类/方法bean管理如。

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

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

答案 2 :(得分:1)

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