Sor*_*cha 9 transactions glassfish multiple-databases persistence-unit ejb-3.0
我试图在Glassfish上部署的Java EE应用程序中的同一事务中使用2个持久性单元.
这两个持久性单元在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>
...
Run Code Online (Sandbox Code Playgroud)
这些持久性单元对应于我在Glassfish中定义的JDBC资源和连接池,如下所示(这里包括一个,因为两者在名称和数据库连接信息之外是相同的):
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
Run Code Online (Sandbox Code Playgroud)
有3个无状态会话bean,LimsServiceBean,AnalysisServiceBean和AnalysisDataTransformationServiceBean.
以下是LimsServiceBean的相关摘录:
@PersistenceContext(unitName = "LIMS")
EntityManager em;
...
public ArrayList<Sample> getLatestLIMSData() {
Query q = em.createNamedQuery("Sample.findBySubTypeStatus");
return new ArrayList<Sample>(q.getResultList());
}
Run Code Online (Sandbox Code Playgroud)
来自AnalysisServiceBean:
@PersistenceContext(unitName = "BeachWater")
EntityManager em;
...
public ArrayList<AnalysisType> getAllAnalysisTypes() {
Query q = em.createNamedQuery("AnalysisType.findAll");
return new ArrayList<AnalysisType>(q.getResultList());
}
Run Code Online (Sandbox Code Playgroud)
并从AnalysisDataTransformationServiceBean:
@EJB
private AnalysisService analysisService;
@EJB
private LimsService limsService;
public void transformData() {
List<AnalysisType> analysisTypes = analysisService.getAllAnalysisTypes();
ArrayList<Sample> samples = limsService.getLatestLIMSData();
Run Code Online (Sandbox Code Playgroud)
对limsService.getLatestLIMSData()的此调用导致以下异常:
[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.
Run Code Online (Sandbox Code Playgroud)
咨询了这个页面,http://msdn.microsoft.com/en-us/library/ms378484.aspx(以及其他许多内容),我尝试将连接池的定义更改为:
Connection Pool:
Name: BEACHWATER_LIMS
Datasource Classname: com.microsoft.sqlserver.jdbc.SQLServerXADataSource
Resource Type: javax.sql.XADataSource
Run Code Online (Sandbox Code Playgroud)
Ping通过Glassfish管理控制台成功,但调用analyzeService.getAllAnalysisTypes()现在抛出异常:
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'."
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
更改Glassfish中连接池的配置:
Connection Pool:
Name: BEACHWATER_LIMS
Datasource Classname: com.microsoft.sqlserver.jdbc.SQLServerXADataSource
Resource Type: javax.sql.XADataSource
Run Code Online (Sandbox Code Playgroud)
按照Senthil Balakrishnan的博客"如何使MSSQL Server XA数据源工作?"中的步骤进行操作.在这里,http://www.senthilb.com/2010/01/how-to-make-xa-datasource-work-in-mssql.html.
重启Glassfish.
为了在一个事务中使用两个持久性单元(以及两个数据源),您确实需要使用XA连接并相应地配置池(其中至少一个,GlassFish支持最后一个代理优化,该优化允许加入一个非XA资源,请参阅http://docs.sun.com/app/docs/doc/820-7695/beanm?a=view)。那是第一个错误。
对于第二个错误,似乎很难说出当前的详细程度。您能否提供堆栈跟踪信息(如果需要,请激活更精细的日志记录)?
| 归档时间: |
|
| 查看次数: |
14314 次 |
| 最近记录: |