使用EJB和JPA时,请使用JTA事务

3

大家好,我需要一些关于下一个问题的帮助:我有一个完美运行的JPA/无状态EJB项目,它只执行简单的查询和持久化操作,但现在我需要执行一组持久化操作,如果有任何一个操作失败,我必须执行回滚操作,所以我找到了JTA可以完成这项工作,使用下面的源代码:

@Stateless
public class ProjectBean implements IProject {

@Resource
javax.transaction.UserTransaction utx;
@PersistenceContext(unitName = "JPADB")
private EntityManager entityManager;
  ...
 //more code

//this is part of a method
try{
utx.begin();
entityManager.joinTransaction();
    for(Project p:projectResultList){
                entityManager.persist(p);
            }
            utx.commit();
        }catch(Exception e){
            e.printStackTrace();
            if(utx != null)
                try {
                    utx.rollback();
                } catch (IllegalStateException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (SecurityException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (SystemException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                //tx.rollback();
        }

这个功能根本不起作用,以下是persistence.xml的内容:

<persistence-unit name="JPADB">
<jta-data-source>java:jboss/datasources/OracleBic</jta-data-source>
    <properties>
        <property name="hibernate.show_sql" value ="true" />
        <property name="hibernate.dialect"  value="org.hibernate.dialect.Oracle10gDialect" />
    </properties>
</persistence-unit>

我希望有人能给我一些提示或建议,我是一个对JPA/JTA概念不熟悉的新手,我尝试了很多在网上找到的代码,但总是会出现不同的错误(线程上的错误事务:期望TransactionImple usertransaction begin,同时使用JTA时无法使用EntityTransaction)。提前感谢。


3
为什么要在bean代码中管理您的事务?您可以让应用服务器来处理它。您只需要在ejb中注入上下文,像这样:@Resource private SessionContext context;,并在异常捕获块中调用context.setRollbackOnly(); - remigio
2个回答

2
你是否已经指示你的AS,你将手动处理事务并在方法级别使用@TransactionManagement(TransactionManagementType.BEAN)?我没有在类级别上看到这个注释。可能你在方法级别上有它,但你的代码片段不足以猜测。否则所有的事务都是容器管理的,你的代码将无法工作。因此,你必须在方法或类级别上放置@TransactionManagement(TransactionManagementType.BEAN),具体取决于需求,或者你可能希望允许容器为你管理事务,然后你必须按照@remigio建议的进行更改。在你的情况下,第二种方法似乎更好。

0

remigio的评论是正确的,@Stateless会话bean使用javax.ejb.@TransactionAttribute控制事务边界,如果注释不存在,则所有公共方法都是TransactionAttribute.REQUIRED。有关更多信息,请参见http://download.oracle.com/otndocs/jcp/ejb-3_0-fr-eval-oth-JSpec/(ejb-3_0-fr-spec-ejbcore.pdf)。

UserTransaction从未在@Stateless会话bean中使用,而是由调用bean的客户端使用,以标记比仅方法调用本身更广泛的事务窗口。


你是对的,在无状态会话Bean中从未使用过UserTransaction。但对于需要更宽事务窗口的客户端,我会使用有状态会话Bean,并注入@PersistenceContext(PersistenceContextType.Extended)。您希望在会话Bean中封装事务划分策略,并且不希望将其暴露给客户端进行管理。 - Sym-Sym

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接