EJB3 - 在事务中使用2个持久性单元(例外:本地事务已经有1个非XA资源) [英] EJB3 - using 2 persistence units within a transaction (Exception: Local transaction already has 1 non-XA Resource)
问题描述
这两个持久性单元是在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'。
有什么想法?
连接池:
名称: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屋!