EJB3 - 在事务中使用2个持久性单元(例外:本地事务已经有1个非XA资源) [英] EJB3 - using 2 persistence units within a transaction (Exception: Local transaction already has 1 non-XA Resource)

查看:510
本文介绍了EJB3 - 在事务中使用2个持久性单元(例外:本地事务已经有1个非XA资源)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这两个持久性单元是在persistence.xml中定义的,这两个持久性单元是在persistence.xml中定义的,如下:

 < persistence-unit name =BeachWater> 
< jta-data-source> jdbc / BeachWater< / jta-data-source>
...
< persistence-unit name =LIMS>
< jta-data-source> jdbc / BeachWaterLIMS< / jta-data-source>
...

这些持久性单元对应于我定义的JDBC资源和连接池在Glassfish中,如下所示(在这里包括一个,因为两者除了名称和数据库连接信息都是相同的):

$ p $ JDBC资源:
JNDI名称:jdbc / BeachWaterLIMS
池名称:BEACHWATER_LIMS

连接池:
名称:BEACHWATER_LIMS
数据源类名:com.microsoft.sqlserver.jdbc。 SQLServerConnectionPoolDataSource
资源类型:javax.sql.ConnectionPoolDataSource

有3个无状态会话Bean LimsServiceBean ,AnalysisServiceBean和AnalysisDataTransformationServiceBean。



以下是来自LimsServiceBean的相关代码片段:

  @PersistenceContext(unitName =LIMS)
EntityManager em;
...
public ArrayList< Sample> getLatestLIMSData(){
Query q = em.createNamedQuery(Sample.findBySubTypeStatus);
返回新的ArrayList< Sample>(q.getResultList());

来自AnalysisServiceBean:

  @PersistenceContext(unitName =BeachWater)
EntityManager em;
...
public ArrayList< AnalysisType> getAllAnalysisTypes(){
Query q = em.createNamedQuery(AnalysisType.findAll);
返回新的ArrayList< AnalysisType>(q.getResultList());
}

并从AnalysisDataTransformationServiceBean获得:

  @EJB 
私有AnalysisService analysisService;

@EJB
私人LimsService limsService;

public void transformData(){
List< AnalysisType> analysisTypes = analysisService.getAllAnalysisTypes();
ArrayList< Sample> samples = limsService.getLatestLIMSData();

调用limsService.getLatestLIMSData()会导致以下异常:

  [exec]导致:javax.ejb.TransactionRolledbackLocalException:从bean引发的异常;嵌套异常是:Exception [TOPLINK-4002](Oracle TopLink Essentials  -  2.1(Build b60e-fcs(12/23/2008))):oracle.toplink.essentials.exceptions.DatabaseException 
[exec]内部异常: java.sql.SQLException:分配连接时出错。原因:java.lang.IllegalStateException:本地事务已经有1个非XA资源:无法添加更多资源。

浏览此页面后, http://msdn.microsoft.com/en-us/library/ms378484.aspx (其中有很多),我试着改变定义连接池到:

 连接池:
名称:BEACHWATER_LIMS
数据源类名:com.microsoft .sqlserver.jdbc.SQLServerXADataSource
资源类型:javax.sql.XADataSource

Ping通过Glassfish管理控制台成功,但现在调用analysisService.getAllAnalysisTypes()会引发异常:

 原因:javax.ejb.TransactionRolledbackLocalException :bean抛出的异常;嵌套异常是:Exception [TOPLINK-4002](Oracle TopLink Essentials  -  2.1(Build b60e-fcs(12/23/2008))):oracle.toplink.essentials.exceptions.DatabaseException 
内部异常:java.sql .SQLException:分配连接时出错。原因:javax.transaction.SystemException

资源管理器正在全局事务之外进行工作javax.transaction.xa.XAException:com.microsoft.sqlserver.jdbc.SQLServerException:无法创建XA控件连接。错误:无法找到存储过程'master..xp_sqljdbc_xa_init_ex'。

有什么想法?

解决方案

更改Glassfish中连接池的配置:

 连接池:
名称:BEACHWATER_LIMS
数据源类名:com.microsoft.sqlserver.jdbc.SQLServerXADataSource
资源类型:javax.sql.XADataSource

按照Senthil Balakrishnan的博客如何使MSSQL Server XA数据源工作?上的步骤进行操作。在这里, http:// www .blackberry.com / 2010/01 / how-to-make-xa-datasource-work-in-mssql.html 。 / p>

I am trying to use 2 persistence units within the same transaction in a Java EE application deployed on Glassfish.

The 2 persistence units are defined in persistence.xml, as follows:

<persistence-unit name="BeachWater">
<jta-data-source>jdbc/BeachWater</jta-data-source>
...
<persistence-unit name="LIMS">
<jta-data-source>jdbc/BeachWaterLIMS</jta-data-source>
...

These persistence units correspond to JDBC resources and connection pools which I had defined in Glassfish as follows (include one here as both are identical apart from names & database connection info):

JDBC Resource:
JNDI Name: jdbc/BeachWaterLIMS
Pool Name: BEACHWATER_LIMS

Connection Pool:
Name: BEACHWATER_LIMS
Datasource Classname: com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource
Resource Type: javax.sql.ConnectionPoolDataSource

There are 3 stateless session beans, LimsServiceBean, AnalysisServiceBean and AnalysisDataTransformationServiceBean.

Here are the relevant snippets from LimsServiceBean:

@PersistenceContext(unitName = "LIMS")
EntityManager em;
...
public ArrayList<Sample> getLatestLIMSData() {
    Query q = em.createNamedQuery("Sample.findBySubTypeStatus");
    return new ArrayList<Sample>(q.getResultList());
}

From AnalysisServiceBean:

@PersistenceContext(unitName = "BeachWater")
EntityManager em;
...
public ArrayList<AnalysisType> getAllAnalysisTypes() {
    Query q = em.createNamedQuery("AnalysisType.findAll");
    return new ArrayList<AnalysisType>(q.getResultList());
}

And from AnalysisDataTransformationServiceBean:

@EJB
private AnalysisService analysisService;

@EJB
private LimsService limsService;

public void transformData() {
    List<AnalysisType> analysisTypes = analysisService.getAllAnalysisTypes();
    ArrayList<Sample> samples = limsService.getLatestLIMSData();

This call to limsService.getLatestLIMSData() caused the following exception:

     [exec] Caused by: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean; nested exception is: Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.1 (Build b60e-fcs (12/23/2008))): oracle.toplink.essentials.exceptions.DatabaseException
 [exec] Internal Exception: java.sql.SQLException: Error in allocating a connection. Cause: java.lang.IllegalStateException: Local transaction already has 1 non-XA Resource: cannot add more resources.

Having consulted this page, http://msdn.microsoft.com/en-us/library/ms378484.aspx (among many others), I tried changing the definition of the connection pools to:

Connection Pool:
Name: BEACHWATER_LIMS
Datasource Classname: com.microsoft.sqlserver.jdbc.SQLServerXADataSource
Resource Type: javax.sql.XADataSource

Ping via the Glassfish admin console succeeds, but call to analysisService.getAllAnalysisTypes() now throws an exception:

Caused by: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean; nested exception is: Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.1 (Build b60e-fcs (12/23/2008))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Error in allocating a connection. Cause: javax.transaction.SystemException

The resource manager is doing work outside a global transaction javax.transaction.xa.XAException: com.microsoft.sqlserver.jdbc.SQLServerException: Failed to create the XA control connection. Error: "Could not find stored procedure 'master..xp_sqljdbc_xa_init_ex'."

Any ideas?

解决方案

Change configuration of connection pool in Glassfish:

Connection Pool:
Name: BEACHWATER_LIMS
Datasource Classname: com.microsoft.sqlserver.jdbc.SQLServerXADataSource
Resource Type: javax.sql.XADataSource

Follow the steps on Senthil Balakrishnan's blog, "How to make MSSQL Server XA Datasource Work?" here, http://www.senthilb.com/2010/01/how-to-make-xa-datasource-work-in-mssql.html.

Restart Glassfish.

这篇关于EJB3 - 在事务中使用2个持久性单元(例外:本地事务已经有1个非XA资源)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆