我正在实现一个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
任何人都知道原因是什么以及如何解决?
答案 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。