EJB3 - использование 2 единиц персистентности в транзакции (Исключение: локальная транзакция уже имеет 1 ресурс не-XA) - PullRequest
9 голосов
/ 09 апреля 2010

Я пытаюсь использовать 2 постоянных модуля в одной транзакции в приложении Java EE, развернутом на Glassfish.

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

Эти постоянные единицы соответствуют ресурсам JDBC и пулам соединений, которые я определил в Glassfish следующим образом (включите один здесь, так как оба идентичны, кроме имен и информации о соединении с базой данных):

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 сессионных компонента без сохранения состояния: 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());
}

Из 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 завершается успешно, но вызов метода 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'."

Есть идеи?

Ответы [ 2 ]

7 голосов
/ 15 апреля 2010

Изменение конфигурации пула соединений в Glassfish:

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

Следуйте инструкциям в блоге Сентила Балакришнана "Как заставить работать источник данных MSSQL Server XA?" здесь http://www.senthilb.com/2010/01/how-to-make-xa-datasource-work-in-mssql.html.

Перезагрузите Glassfish.

5 голосов
/ 10 апреля 2010

Чтобы использовать два постоянных блока (и, следовательно, два источника данных) в транзакции, вам действительно необходимо использовать подключения XA и соответствующим образом настроить свои пулы (по крайней мере, один из них GlassFish поддерживает последнюю оптимизацию агента, которая позволяет подключиться один ресурс не XA, см. http://docs.sun.com/app/docs/doc/820-7695/beanm?a=view). Это было для первой ошибки.

По второй ошибке трудно сказать что-либо с текущим уровнем детализации. Не могли бы вы предоставить трассировку стека (при необходимости активировать более точное ведение журнала)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...