Spring 在JMSTemplate中处理SetSession的确切含义是什么?

Spring 在JMSTemplate中处理SetSession的确切含义是什么?,spring,transactions,spring-transactions,spring-jms,jmstemplate,Spring,Transactions,Spring Transactions,Spring Jms,Jmstemplate,请解释我是否正确理解了Spring文档 Spring docs声明: (…)在非托管环境中使用JmsTemplate时,可以通过使用属性SessionTransact和sessionAcknowledgeMode指定这些值(事务和确认模式) 当您将PlatformTransactionManager与JmsTemplate一起使用时,该模板始终具有事务性JMS会话。(..) (顺便说一句,这是真的-会话是事务性的) Javadoc声明: JMS会话的默认设置为“未处理”和“自动确认”。根据Jav

请解释我是否正确理解了Spring文档

Spring docs声明:

(…)在非托管环境中使用JmsTemplate时,可以通过使用属性SessionTransact和sessionAcknowledgeMode指定这些值(事务和确认模式)

当您将PlatformTransactionManager与JmsTemplate一起使用时,该模板始终具有事务性JMS会话。(..)

(顺便说一句,这是真的-会话是事务性的)

Javadoc声明:

JMS会话的默认设置为“未处理”和“自动确认”。根据JavaEE规范的定义,当在活动事务中创建JMS会话时,事务和确认参数将被忽略,无论是JTA事务还是Spring管理的事务

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

我调试了为什么它不是真的,我发现:

resourceHolderToUse.setSynchronizedWithTransaction(true)
与文档对齐

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

因为
resourceFactory
是org.springframework.jms.core.JmsTemplate.JmsTemplate.JmsTemplateResourceFactory#是同步的LocalTransactionalLowed,它指向
JmsTemplate#sessionTransact

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

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


我对文档的理解正确吗?这里真的有bug吗?

在M.Deinum的指导下,我做了更多的实验,似乎我错误地理解了术语Spring托管事务

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

  • 如果
    platformTransactionManager
    JtaTransactionManager
    且事务已启动,则Spring管理事务;忽略JMS模板属性SessionTransact,并且JMS模板是事务的一部分
  • 如果
    platformTransactionManager
    DataSourceTransactionManager
    JpaTransactionManager
    ,则
    • 如果
      sessionTransact
      为false,则JMS模板不在事务中
    • 如果
      sessionTransact
      为true,JMS模板将与事务同步:在JDBC/JPA事务上的回调/回滚之后,JMS事务将调用相应的提交/回滚

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

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

  • 如果
    platformTransactionManager
    JtaTransactionManager
    且事务已启动,则Spring管理事务;忽略JMS模板属性SessionTransact,并且JMS模板是事务的一部分
  • 如果
    platformTransactionManager
    DataSourceTransactionManager
    JpaTransactionManager
    ,则
    • 如果
      sessionTransact
      为false,则JMS模板不在事务中
    • 如果
      sessionTransact
      为true,JMS模板将与事务同步:在JDBC/JPA事务上的回调/回滚之后,JMS事务将调用相应的提交/回滚

  • 如果该方法表示所有
    均为SynchronizedLocalTransactionalLowed
    ,则该名称适用于本地事务(即
    JmsTransactionManager
    ),但这不适用于由JTA而非Spring(即非本地事务)驱动的托管(J(2)EE)环境.@M.Deinum在我的代码中,我调用
    platformTransactionManager.getTransaction()
    ,并根据“不管是JTA事务还是Spring管理的事务。”我希望应该忽略
    sessionTransactive
    。我说的对吗?只有当事务是本机JMS事务或托管事务时,它才能参与事务。当它是像JPA这样的其他东西时,它不能参与,因为它无法提交,并且需要自己管理它(这也在ConnectionFactoryUtils中有文档记录)。如果该方法表示所有
    都是同步的LocalTransactionalLowed
    ,这是用于本地事务的(即
    JmsTransactionManager
    )但是,这不适用于托管(J(2)EE)环境,其中事务由JTA而不是Spring(即非本地事务)驱动。@M.Deinum在我的代码中调用
    platformTransactionManager.getTransaction()
    ,并根据“不管是JTA事务还是Spring托管事务”我希望
    sessiontransact
    应该被忽略。我说的对吗?只有当事务是本机JMS事务或托管事务时,它才能参与事务。当它是像JPA这样的其他东西时,它不能参与,因为它不能提交并且需要自己管理它(这也在ConnectionFactoryUtils中有文档记录)。
    if (resourceHolderToUse != resourceHolder) {
      TransactionSynchronizationManager.registerSynchronization(
        new JmsResourceSynchronization(resourceHolderToUse, connectionFactory,
                                 
     resourceFactory.isSynchedLocalTransactionAllowed()));
     resourceHolderToUse.setSynchronizedWithTransaction(true);
     TransactionSynchronizationManager.bindResource(connectionFactory, resourceHolderToUse);
    }