How to prevent “Local transaction already has 1 non-XA Resource” exception?

风格不统一 提交于 2019-12-22 04:15:12

问题


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


回答1:


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.




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/2687121/how-to-prevent-local-transaction-already-has-1-non-xa-resource-exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!