Транзакции Container Manager и JackRabbit

В настоящее время у меня есть Jackrabbit 2.6.4, развернутый в Glassfish 4 с использованием JCA rar.

Я использую MySql и настроил источник данных в Glassfish для доступа к базе данных. Я использую тот же источник данных в репозитории Jackrabbit.xml при настройке RepositoryManager.

Если я ввожу репозиторий через аннотацию @Resource в управляемый компонент контейнера, который не запускает транзакцию автоматически, все работает так, как ожидалось.

Если я внедряю репозиторий через аннотацию @Resource в EJB (что приводит к транзакции, управляемой контейнером), я получаю следующую трассировку стека при попытке использовать репозиторий:

javax.resource.spi.LocalTransactionException: невозможно вызвать фиксацию, когда autocommit=true на com.sun.gjc.spi.LocalTransactionImpl.commit(LocalTransactionImpl.java:112) на com.sun.enterprise.resource.ConnectorXAResource.commit(ConnectorXAResource .java:124) ... Вызвано: java.sql.SQLException: невозможно вызвать фиксацию, когда autocommit=true в com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927) в com.mysql.jdbc. SQLError.createSQLException(SQLError.java:924) в com.mysql.jdbc.ConnectionImpl.commit(ConnectionImpl.java:1724) в com.sun.gjc.spi.LocalTransactionImpl.commit(LocalTransactionImpl.java:106) ... 72 подробнее ]] [2013-10-28T14:49:29.646-0700] [glassfish 4.0] [ПРЕДУПРЕЖДЕНИЕ] [jts.unexpected_error_occurred_twopc_commit] [javax.enterprise.system.core.transaction.com.sun.jts.jtsxa] [tid: _ThreadID=33 _ThreadName=http-listener-1(3)] [timeMillis: 1382996969646] [levelValue: 900] [[ JTS5067: Непредвиденная ошибка при фиксации javax.transacti on.xa.XAException: javax.resource.spi.LocalTransactionException: невозможно вызвать фиксацию, когда autocommit=true в com.sun.enterprise.resource.ConnectorXAResource.handleResourceException(ConnectorXAResource.java:115) в com.sun.enterprise.resource .ConnectorXAResource.commit(ConnectorXAResource.java:126) ... ]]

Глядя на документацию Jackrabbit, говорится:

Если вы используете менеджер постоянства базы данных, сконфигурированное соединение с базой данных не должно находиться под контролем внешнего менеджера транзакций. Jackrabbit реализует поддержку распределенных транзакций XA на более высоком уровне и ожидает полного контроля над базовым соединением с базой данных.

Учитывая это, как/могу ли я настроить Jackrabbit и Glassfish, чтобы позволить транзакциям, управляемым контейнером, и транзакциям, управляемым Jackrabbit, участвовать вместе в одной и той же глобальной транзакции?

Я попытался настроить адаптер JCA Jackrabbit и пул подключений к источнику данных для использования транзакций XA. Я также установил для свойства JCA Jackrabbit bindSessionToTransaction значение true. Ни один из них не работал.


person lucasweb    schedule 28.10.2013    source источник


Ответы (1)


После некоторых проб и ошибок я пришел к следующему подходу:

  1. Создайте пул соединений JDBC в Glassfish, который используется для доступа к таблицам репозитория Jackrabbit.
  2. Установите тип ресурса на javax.sql.DataSource и включите «Нетранзакционные соединения».
  3. Создайте ресурс JDBC, который можно использовать для доступа к пулу соединений JDBC Jackrabbit. Используйте имя JNDI, определенное в этом ресурсе в репозитории Jackrabbit.xml, чтобы настроить диспетчер постоянства и т. д.
  4. Создайте пулы соединений Connector с помощью адаптера ресурсов Jackrabbit-jca.
  5. Установить поддержку транзакций на XATransaction
  6. Добавьте свойство bindSessionToTransaction и установите для него значение true.
  7. Создайте ресурс соединителя, который можно использовать для внедрения репозитория в EJB.

Я протестировал это с EJB без сохранения состояния, и он работает без ошибок.

Я также создал второй пул соединений JDBC типа javax.sql.DataSource и ресурс JDBC, который указывает на отдельную базу данных, которая поддерживает другие таблицы приложений, и создал файл persistence.xml, который использует источник данных.

Затем я изменил как репозиторий, так и таблицы в базе данных приложений (используя JPA) и подтвердил, что при откате транзакции изменения в таблицах репо и приложений откатываются корректно.

Я считаю, что это правильный подход, поскольку он позволяет Jackrabbit полностью контролировать подключение к базе данных, но при этом участвовать в транзакции, управляемой контейнером, в качестве ресурса XA.

Я протестировал второй источник данных как XADataSource, так и не-XA DataSource, и оба подхода сработали. Я предполагаю, что это не обязательно должен быть XADataSource, поскольку в транзакции нет других источников данных, отличных от XA, и он участвует в глобальной транзакции через LLR (регистрация последнего ресурса).

Обновление 1:

Оказывается, вы также можете заставить это работать, минуя источник данных репо и настроив URL-адрес JDBC непосредственно в xml репозитория. Одно из преимуществ этого заключается в том, что при кластеризации репо вам не нужно создавать источник данных в каждом экземпляре Glassfish, вместо этого вы можете просто скопировать репозиторий.xml и изменить идентификатор узла кластера.

person lucasweb    schedule 29.10.2013