【问题标题】:EJB3 - using 2 persistence units within a transaction (Exception: Local transaction already has 1 non-XA Resource)EJB3 - 在事务中使用 2 个持久性单元(例外:本地事务已经有 1 个非 XA 资源)
【发布时间】:2011-02-06 01:59:03
【问题描述】:

我正在尝试在 Glassfish 上部署的 Java EE 应用程序中的同一事务中使用 2 个持久性单元。

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>
...

这些持久性单元对应于我在 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

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

以下是来自 LimsServiceBean 的相关 sn-ps:

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

来自 AnalysisServiceBean:

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

并来自 AnalysisDataTransformationServiceBean:

@EJB
private AnalysisService analysisService;

@EJB
private LimsService limsService;

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

对 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.

在查阅了此页面 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

通过 Glassfish 管理控制台 Ping 成功,但现在调用 analysisService.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'."

有什么想法吗?

【问题讨论】:

标签: transactions glassfish ejb-3.0 multiple-databases persistence-unit


【解决方案1】:

为了在一个事务中使用两个持久性单元(因此是两个数据源),您确实需要使用 XA 连接并相应地配置您的池(至少其中一个,GlassFish 支持允许登记的最后一个代理优化一个非 XA 资源,请参阅 http://docs.sun.com/app/docs/doc/820-7695/beanm?a=view)。这是第一个错误。

对于第二个错误,以目前的细节水平似乎很难说什么。您能否提供堆栈跟踪(如果需要,激活更精细的日志记录)?

【讨论】:

  • 谢谢帕斯卡。此后,我在日志中发现了更多详细信息:资源管理器正在全局事务 javax.transaction.xa.XAException 之外工作:com.microsoft.sqlserver.jdbc.SQLServerException:无法创建 XA 控制连接。错误:“找不到存储过程 'master..xp_sqljdbc_xa_init_ex'。”我在这里找到了建议的解决方案senthilb.com/2010/01/…,并已请求在服务器上进行相关更改。当我重新测试时会在这里更新。
  • @Sorcha 感谢您的反馈。不要犹豫,在更新后发表评论,以便我收到通知。但我感觉你走在正确的轨道上!
  • 查看添加的答案。现在完美运行。再次感谢您的贡献。
  • 我在使用 WLS 10.3 和 2 数据源、Oracle 和 Informix 时遇到了类似的问题。非常有帮助。谢谢。
【解决方案2】:

在 Glassfish 中更改连接池的配置:

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

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

重新启动 Glassfish。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-02-22
  • 2017-06-11
  • 2010-10-26
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
  • 2017-02-17
  • 1970-01-01
相关资源
最近更新 更多