如何防止“本地事务已经拥有 1 个非 XA 资源”例外?

发布于 2024-08-29 14:13:14 字数 926 浏览 3 评论 0原文

我在无状态 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 事务进行注释以避免出现此异常。当我从 javaFX 小程序调用这些方法时,一切都按预期工作。现在我尝试从 JAX-RS Web 服务调用它们(我没有看到任何逻辑差异,因为在这两种情况下 ejb 都是在初始上下文中查找的)并且我不断收到此异常。当我在 glassfish 2.1 连接池中设置 XADatasource 时,我在 em2 上遇到了空指针异常。

有什么想法下一步要尝试什么吗?

问候

I'm using 2 PU in stateless EJB and each of them is invoked on one method:

@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;
}

Those methods are annotated with REQUIRES_NEW transcaction to avoid this exception. When I was calling these method from javaFX applet, all worked as expected. Now I'm trying to call them from JAX-RS webservice (I don't see any logical difference as in both cases ejb was looked up in initial context) and I keep getting this exception. When I set up XADatasource in glassfish 2.1 connection pools, I got nullpointer exception on em2.

Any ideas what to try next?

Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沫尐诺 2024-09-05 14:13:15

我在无状态 EJB 中使用 2 个 PU,每个 PU 都在一个方法上调用

。但是您正在从第一个方法调用第二个方法,因此您正在执行分布式事务,并且需要为此使用 XA(至少对于其中一个资源,因为 GlassFish 支持 最后一个代理优化允许涉及一个非 XA 资源)。换句话说,将您的数据源之一设置为 XADataSource 是一种可行的方法。

如果您在执行此操作时遇到错误,请添加有关您具体操作的详细信息以及堆栈跟踪。

I'm using 2 PU in stateless EJB and each of them is invoked on one method

Indeed. But you're calling the second method from the first one so you're doing a distributed transaction and you need to use XA for this (at least for one of the resource since GlassFish supports the last agent optimization allowing to involve one non-XA resource). In other words, setting one of your datasource as a XADataSource is the way to go.

If you get an error when doing this, please add details about what you did exactly and the stacktrace.

饭团 2024-09-05 14:13:15

好的,

现在已经解决了。我会分享以防万一有人遇到类似的事情。
整个问题在于 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>

现在就像魅力一样工作。

Ok,

it's solved now. I'll share just in case somebody got tackled by similar thing.
Whole problem was with netbeans deploying. They overwrite the settings in glassfish connection pool and when you set them proper at runtime, you got npe's or missing password silly stuff. The place to edit this is sun-resources.xml. XML element has attributes datasource-classname and rs-type. What needs to be done in case of Derby database is:

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

Works like a charm now.

错爱 2024-09-05 14:13:15

当调用第一个方法的第二个方法时,它不是 EJB 方法调用。它仅将其视为常规方法调用,并且不查看@TransactionAttribute。如果您想要调用同一个 EJB,您可以注入 SessionContext 并调用 getBusinessObject。然后调用返回的 EJB 上的方法。

When calling the second method from the first, it is not an EJB method call. It treats it as just a regular method call and does not look at @TransactionAttribute. If you want a call to the same EJB, you can inject the SessionContext and call getBusinessObject. Then call the method on the returned EJB.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文