Что именно означает setSessionTransacted в JMSTemplate? - PullRequest
0 голосов
/ 21 октября 2019

Пожалуйста, объясните мне, если я правильно понял документацию Spring.

Состояния документов Spring: https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#jms-tx

(...) Когда вы используете JmsTemplate в неуправляемой среде,Вы можете указать эти значения ( режимы транзакции и подтверждения ) через использование свойств sessionTransacted и sessionAcknowledgeMode.

Когда вы используете PlatformTransactionManager с JmsTemplate, шаблону всегда дается транзакционный JMS-сеанс. (..)

(Кстати, сеанс является транзакционным)

Состояния Javadoc: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jms/core/JmsTemplate.html

Стандартными настройками для сеансов JMS являются "не передаваемые" и "автоматическое подтверждение". Как определено в спецификации Java EE, параметры транзакции и подтверждения игнорируются при создании сеанса JMS внутри активной транзакции, независимо от того, является ли транзакция JTA или транзакция управляемой Spring .

* 1025. *

Я понял, что если транзакция активна, параметры транзакции сеанса JMS Template игнорируются - , что верно - и в сеансе должна участвовать активная транзакция - , что не соответствует действительности .

Я отлаживаю, почему это не так, и обнаружил: https://github.com/spring-projects/spring-framework/blame/master/spring-jms/src/main/java/org/springframework/jms/connection/ConnectionFactoryUtils.java#L353

if (resourceHolderToUse != resourceHolder) {
  TransactionSynchronizationManager.registerSynchronization(
    new JmsResourceSynchronization(resourceHolderToUse, connectionFactory,

 resourceFactory.isSynchedLocalTransactionAllowed()));
 resourceHolderToUse.setSynchronizedWithTransaction(true);
 TransactionSynchronizationManager.bindResource(connectionFactory, resourceHolderToUse);
}

Строка resourceHolderToUse.setSynchronizedWithTransaction(true) соответствует документации.

Проблема здесь: resourceFactory.isSynchedLocalTransactionAllowed()

Поскольку resourceFactory является org.springframework.jms.core.JmsTemplate.JmsTemplateResourceFactory # isSynchedLocalTransactionAllowed, который указывает на JmsTemplate#sessionTransacted.

Вывод: согласно документации,если транзакция активна, JmsTemplate#sessionTransacted следует игнорировать. Но это не так - хотя сеанс является транзакционным, он не может не участвовать в фиксации.

JmsTemplate#sessionTransacted окончательно отображается на ConnectionFactoryUtils.JmsResourceSynchronization#transacted, а default = false предотвращает вызов фиксации в конце транзакции (JmsResourceSynchronization "считает, что"что она не участвует в транзакции)

Правильно ли я понимаю документацию и здесь действительно есть ошибка?

1 Ответ

0 голосов
/ 23 октября 2019

Руководствуясь М. ​​Дейном, я провел больше экспериментов и, похоже, неправильно понял термин Управляемая Spring-транзакция

Я просто подумал, что управляемая Spring-транзакция запускается platformTransactionManager. Но:

  1. Если platformTransactionManager равно JtaTransactionManager и транзакция запущена, это IS Управляемая транзакция Spring;Атрибут шаблона JMS sessionTransacted игнорируется, а шаблон JMS является частью транзакции
  2. , если platformTransactionManager равен DataSourceTransactionManager или JpaTransactionManager, тогда
    • , если sessionTransacted равно false, JMS-шаблон не находится в транзакции
    • , если sessionTransacted истина, JMS-шаблон синхронизируется с транзакцией: после обратного вызова / отката в транзакции JDBC / JPA соответствующая транзакция / откат вызывается для транзакции JMS
...