Мое приложение работает на IBM WebSphere 9 (JVM 8, поэтому Spring 5.3.39 — самая последняя версия, на которую я могу перейти) и использует JmsTemplate для отправки сообщений в очередь IBM MQ. Для параметра sessionTransacted установлено значение true, в Spring 4.3.5 все работает нормально, а в версии 5.3.39 я получаю исключение IllegalStateException с этой трассировкой стека:
Код: Выделить всё
Caused by: javax.jms.IllegalStateException: Method not permitted in global transaction
null
at com.ibm.ejs.jms.JMSSessionHandle.checkNotInGlobalTransaction(JMSSessionHandle.java:1385)
at com.ibm.ejs.jms.JMSSessionHandle.commit(JMSSessionHandle.java:700)
at com.ibm.ejs.jms.JMSSessionHandle.commit(JMSSessionHandle.java:663)
at org.springframework.jms.support.JmsUtils.commitIfNecessary(JmsUtils.java:218)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:1278)
at org.springframework.jms.core.JmsTemplate.lambda$send$3(JmsTemplate.java:586)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:504)
at orgmsTemplate.send(JmsTemplate.java:584)
at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:661)
at it.[REDACTED].sendMessage[REDACTED].java:839)
at it.[REDACTED].java:156)
at it.[REDACTED].java:63)
at it.[REDACTED].java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-2)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
Код: Выделить всё
catch (IllegalStateException illegalStateException) {}
Еще одна странность: согласно документации Spring (комментарий в коде), когда транзакция управляется контейнером, свойство sessionTransacted в JmsTemplate должно игнорироваться. Но на самом деле это не то, что происходит.
Во время отладки я обнаружил, что JmsUtils.isSessionLocallyTransacted возвращает true, даже если в сеансе выполняются глобальные транзакции. Это происходит потому, что isSessionTransactional возвращает true из-за того, что TransactionSynchronizationManager.getResource(cf) возвращает значение null.
Посмотрев глубже в TransactionSynchronizationManager.getResource(cf), я заметил, что doGetResource возвращает значение null при получении карты из ресурсов:
Код: Выделить всё
TransactionSynchronizationManager.doGetResource
...
Map map = resources.get();
if (map == null) {
return null;
}
...
У вас есть какие-либо предложения по этому поводу? Я впервые глубоко копаюсь в Spring Framework, поэтому, вероятно, что-то упускаю. Но я сейчас переношу сотни приложений, и это серьезная проблема.
Подробнее здесь: https://stackoverflow.com/questions/798 ... -a-message
Мобильная версия