Жизненный цикл JCA ManagedConnection
В настоящее время я разработал исходящий адаптер JCA (с поддержкой LocalTransaction), и у меня возникли некоторые проблемы с управлением соединением. Мой адаптер работает хорошо, за исключением того, что сервер (WebLogic 12c) не помещает ManagedConnections обратно в пул. Согласно JavaDoc, сервер должен вызывать ManagedConnection.cleanup()
переинициализировать соединение и вернуть его в пул, но это не так.
Когда я использую адаптер из EJB, сервер создает новое ManagedConnection, начинает новую транзакцию, фиксирует ее, но не вызывает ManagedConnection.cleanup()
метод и не возвращает его обратно в пул.
Ниже вы можете увидеть мой тестовый компонент:
@Stateless(mappedName = "TestingBean")
@Local(value = TestingBeanLocal.class)
@Remote(value = TestingBeanRemote.class)
@TransactionManagement(value = TransactionManagementType.CONTAINER)
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
public class TestingBean implements TestingBeanCommon{
@Resource(mappedName = "eis/myJCA")
private MyDataSource dataSource;
@Override
public void performTestAction(String param1, String param2) {
MyConnection connection = dataSource.getMyConnection();
connection.performAction(ActionFactory.getSomeAction(param1, param2));
}
}
После 10 вызовов я получаю следующее:
Получил начальный контекст javax.ejb.EJBException: EJB Exception:; Вложенное исключение: java.lang.RuntimeException: javax.resource.spi.ApplicationServerInternalException: невозможно получить соединение для pool = "eis/myJCA", weblogic.common.resourcepool.ResourceLimitException: настроен максимальный предел (0) для числа потокам разрешено ждать достижения ресурса для пула eis / myJCA
Как вы заметили, он использует новую транзакцию для каждого вызова (REQUIRES_NEW
атрибуты). Сервер сначала создает новый экземпляр ManagedConnection, а затем пул соединений достигает максимальной емкости.
Из трассировки журналов ясно, что ни одного вызова ManagedConnection.cleanup()
происходит, и каждое соединение в пуле занято. Я прочитал спецификацию JCA и обнаружил, что адаптер может отправлять события жизненного цикла слушателям, используя функции обратного вызова, но любая попытка использовать эти обратные вызовы слушателей событий заканчивалась новым исключением:
javax.ejb.EJBException: BEA1-001471C1E76DE5A4E067; вложенное исключение: weblogic.transaction.nonxa.NonXAException: java.lang.IllegalStateException: [Connector:199175] Это ManagedConnection управляется контейнером для его транзакционного поведения и было зачислено в транзакцию JTA контейнером; Приложение / адаптер не должны вызывать локальную транзакцию API start / commit / rollback. Отклонить событие LOCAL_TRANSACTION_COMMITTED от адаптера. javax.ejb.EJBException: EJB Exception:; вложенное исключение: java.lang.IllegalStateException: [Connector: 199175] Это ManagedConnection управляется контейнером для его транзакционного поведения и было зачислено в транзакцию JTA контейнером; Приложение / адаптер не должны вызывать локальную транзакцию API start / commit / rollback. Отклонить событие LOCAL_TRANSACTION_ROLLEDBACK от адаптера.
Я полагаю, что WebLogic не ожидает какого-либо события (может быть, я отправил неправильное?).
Итак, что я делаю не так? Как заставить сервер вернуть подключения к пулу?
UPD: я обнаружил, что события подключения очень важны для сервера. Сервер управляет соединениями на основе информации о событиях, которые были отправлены слушателям, которые он регистрирует в ManagedConnection. Теперь я поддерживал события в моем адаптере, но WebLogic по-прежнему не хочет возвращать соединения в пул. В настоящее время я получаю следующие события в журналах:
- LOCAL_TRANSACTION_STARTED
- CONNECTION_CLOSED
- LOCAL_TRANSACTION_COMMITTED
Это выглядит нормально для меня (событие CONNECTION_CLOSED означает, что приложение закрыло соединение, я добавил метод close, который отправляет это событие). Фиксация прошла успешно и никаких исключений не появляется. Кажется, что я отправил события в правильном порядке (ранее WebLogic генерировал исключения, но теперь прекращает это делать), но сервер по-прежнему не устанавливает соединения обратно в пул.
Я сбит с толку.
1 ответ
Кажется, я решил эту проблему. Когда я посмотрел в консоли WebLogic, я обнаружил, что экземпляры ManagedConnection имеют -1 активных обработчиков. Поэтому я решил прокомментировать MyConnection.close()
вызов метода, который я добавил в свой тестовый компонент для отправки CONNECTION_CLOSED
событие. После того, как эти изменения были сделаны, пул соединений начал работать отлично. Я попытался изменить тестирующий компонент и установить для его атрибута транзакции значение NOT_SUPPORTED
, После этого ManagedConnections
в пуле был 1 активный обработчик. Так что я положил обратно MyConnection.close()
пул линий и подключений снова начинает работать.
Я предполагаю, что отправка CONNECTION_CLOSED
событие неверно в случае распространения транзакции. Также я предполагаю, что метод ManagedConnection.close()
, который отправляет CONNECTION_CLOSED
событие должно использоваться в случае одной транзакции. Но мне кажется странным, что WebLogic не хочет убирать ManagedConnections
и положить их обратно, чтобы вытащить, если они имеют отрицательное количество активных обработчиков.
Большое спасибо за помощь.