JMSTemplate 中的 setSessionTransacted 到底意味着什么?

mic*_*ldo 3 spring transactions jmstemplate spring-transactions spring-jms

如果我正确理解 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 管理的事务,事务和确认参数都将被忽略。

我知道,如果事务处于活动状态,JMS 模板会话事务设置将被忽略 -这是正确的- 并且会话应该参与活动事务 -这是不正确的

我调试为什么它不正确,我发现: 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);
}
Run Code Online (Sandbox Code Playgroud)

该线resourceHolderToUse.setSynchronizedWithTransaction(true)与文档对齐。

这里的问题是:resourceFactory.isSynchedLocalTransactionAllowed()

因为resourceFactoryorg.springframework.jms.core.JmsTemplate.JmsTemplateResourceFactory#isSyncchedLocalTransactionAllowed 指向JmsTemplate#sessionTransacted.

结论:根据文档,如果事务处于活动状态,JmsTemplate#sessionTransacted则应忽略。但事实并非如此——尽管会话是事务性的,但不能不参与提交。

JmsTemplate#sessionTransacted最终映射到ConnectionFactoryUtils.JmsResourceSynchronization#transacted并且 default=false 防止在事务结束时调用提交(JmsResourceSynchronization“认为”它不参与事务)

我对文档的理解是否正确并且这里确实存在错误?

mic*_*ldo 5

在M. Deinum的指导下,我做了更多的实验,看来我错误地理解了Spring管理事务这个术语

我只是认为 Spring 管理的事务是由 启动的platformTransactionManager。但:

  1. 如果platformTransactionManagerJtaTransactionManager并且事务已启动,则它Spring 管理的事务;JMS 模板属性sessionTransacted被忽略,JMS 模板是事务的一部分
  2. 如果platformTransactionManagerDataSourceTransactionManager或者JpaTransactionManager那么
    • 如果sessionTransacted为 false,则 JMS 模板不在事务中
    • 如果sessionTransacted为 true,则 JMS 模板与事务同步:在 JDBC/JPA 事务回调/回滚之后,在 JMS 事务上调用对应的提交/回滚