【发布时间】:2020-02-17 20:21:40
【问题描述】:
如果我对 Spring 文档的理解正确,请解释一下。
Spring 文档状态:https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#jms-tx
(...)当您在非托管环境中使用 JmsTemplate 时,您可以通过使用属性 sessionTransacted 和 sessionAcknowledgeMode 来指定这些值(事务和确认模式)。
当您将 PlatformTransactionManager 与 JmsTemplate 一起使用时,模板总是被赋予一个事务性 JMS 会话。(..)
(顺便说一句,这是真的 - 会话是事务性的)
JMS 会话的默认设置是“未处理”和“自动确认”。正如 Java EE 规范所定义的,当在活动事务中创建 JMS 会话时,事务和确认参数将被忽略,无论是 JTA 事务还是 Spring 管理的事务。
我知道如果事务处于活动状态,JMS 模板会话事务设置将被忽略 - 这是真的 - 并且会话应该参与活动事务 - 这是不正确的强>.
if (resourceHolderToUse != resourceHolder) {
TransactionSynchronizationManager.registerSynchronization(
new JmsResourceSynchronization(resourceHolderToUse, connectionFactory,
resourceFactory.isSynchedLocalTransactionAllowed()));
resourceHolderToUse.setSynchronizedWithTransaction(true);
TransactionSynchronizationManager.bindResource(connectionFactory, resourceHolderToUse);
}
resourceHolderToUse.setSynchronizedWithTransaction(true) 行是对齐文档。
这里的问题:resourceFactory.isSynchedLocalTransactionAllowed()
因为resourceFactory 是指向JmsTemplate#sessionTransacted 的org.springframework.jms.core.JmsTemplate.JmsTemplateResourceFactory#isSynchedLocalTransactionAllowed。
结论:
根据文档,如果事务处于活动状态,则应忽略 JmsTemplate#sessionTransacted。但事实并非如此——虽然会话是事务性的,但不能不参与提交。
JmsTemplate#sessionTransacted 最终映射到 ConnectionFactoryUtils.JmsResourceSynchronization#transacted 并且 default=false 防止在事务结束时调用提交(JmsResourceSynchronization “认为”它不参与事务)
我对文档的理解正确吗,这里真的有错误吗?
【问题讨论】:
-
该方法的名称
isSynchedLocalTransactionAllowed用于本地事务(即JmsTransactionManager),但这不适用于托管 (J(2)EE) 环境,其中事务由 JTA 而不是 Spring 驱动(即不是本地事务)。 -
@M.Deinum 在我的代码中我调用
platformTransactionManager.getTransaction()并根据“无论是 JTA 事务还是 Spring 管理的事务”。我希望sessionTransacted应该被忽略。我说的对吗? -
只有原生JMS事务或托管事务才能参与事务。当它是 JPA 之类的其他东西时,它不能参与,因为它不能提交并且它需要自己管理它(这也记录在 ConnectionFactoryUtils 中)。
标签: spring transactions spring-transactions spring-jms jmstemplate