代码之家  ›  专栏  ›  技术社区  ›  zeratul021

如何防止“本地事务已经有1个非xa资源”异常?

  •  7
  • zeratul021  · 技术社区  · 14 年前

    我在无状态ejb中使用2个pu,每个pu都在一个方法上调用:

    @PersistenceContext(unitName="PU")
    private EntityManager em;
    @PersistenceContext(unitName="PU2")
    private EntityManager em2;
    
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW )
    public void getCandidates(final Integer eventId) throws ControllerException {
        ElectionEvent electionEvent = em.find(ElectionEvent.class, eventId);
        ...
        Person person = getPerson(candidate.getLogin());
        ...
    }
    
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW )
    private Person getPerson(String login) throws ControllerException {
        Person person = em2.find(Person.class, login);
        return person;
    }
    

    这些方法被注释为Requires_New Transaction以避免此异常。当我从javafx applet调用这些方法时,一切正常。现在我试图从jax-rs webservice调用它们(我看不出任何逻辑差异,因为在这两种情况下,ejb都是在初始上下文中查找的),并且我一直得到这个异常。当我在glassfish 2.1连接池中设置xadatasource时,在em2上出现了空指针异常。

    你知道下一步该怎么做吗?

    当做

    3 回复  |  直到 11 年前
        1
  •  5
  •   Paul Vargas    11 年前

    好啊,

    现在解决了。我来分享一下,以防有人被类似的事情缠住。 整个问题是netbeans的部署。它们覆盖glassfish连接池中的设置,当您在运行时正确设置这些设置时,您会得到npe或丢失密码的愚蠢的东西。编辑的地方是 sun-resources.xml文件 . xml元素具有属性datasource classname和rs type。对于derby数据库,需要做的是:

    <jdbc-connection-pool ... 
            datasource-classname="org.apache.derby.jdbc.ClientXADataSource" 
            res-type="javax.sql.XADataSource">
       ...
    </jdbc-connection-pool>
    

    现在很有魅力。

        2
  •  2
  •   Pascal Thivent    14 年前

    我在无状态ejb中使用了2个pu,每个pu都在一个方法上调用

    的确。但是您正在从第一个方法调用第二个方法,因此您正在执行一个分布式事务,您需要为此使用xa(至少为一个资源使用xa,因为glassfish支持 last agent optimization 允许包含一个非xa资源)。换句话说,将一个数据源设置为 XADataSource 是一条路。

    如果您在执行此操作时出错,请添加有关您所做操作的详细信息 确切地 还有StackTrace。

        3
  •  1
  •   ElderMael    12 年前

    从第一个方法调用第二个方法时,它不是一个ejb方法调用。它将其视为一个常规方法调用,而不查看 @TransactionAttribute . 如果您希望调用同一个ejb,可以注入 SessionContext 并打电话 getBusinessObject . 然后对返回的ejb调用方法。