Spring integration 同步JMS消息队列和JDBC事务-是否需要事务代理

Spring integration 同步JMS消息队列和JDBC事务-是否需要事务代理,spring-integration,spring-jms,Spring Integration,Spring Jms,我们需要将JMS队列中的消息持久化到事务中的数据库中,以确保在DB持久化期间抛出任何错误时不会确认JMS消息。 根据此处提供的解决方案- 下面是我得出的方法 <int-jms:message-driven-channel-adapter id="jmsIn" transaction-manager="transactionManager" connection-factory="sConnectionFactory" destination-name="emsQue

我们需要将JMS队列中的消息持久化到事务中的数据库中,以确保在DB持久化期间抛出任何错误时不会确认JMS消息。 根据此处提供的解决方案- 下面是我得出的方法

<int-jms:message-driven-channel-adapter id="jmsIn"
    transaction-manager="transactionManager"
    connection-factory="sConnectionFactory"
    destination-name="emsQueue"
    acknowledge="transacted" channel="jmsInChannel"/>

<int:channel id=" jmsInChannel " />

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
    <property name="url" value="jdbc:hsqldb:mem:testdb" />
</bean>

<!-- Transaction manager for a datasource -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
</bean>

    <bean id="sconnectionFactory"       class="org.springframework.jms.connection.TransactionAwareConnectionFactoryProxy">
        <property name="targetConnectionFactory">
            <bean class="project.TestConnectionFactory">

            </bean>
        </property>
        <property name="synchedLocalTransactionAllowed" value="true" />
    </bean>

请确认理解是否正确。此外,还有以下问题

  • 此场景中是否需要TransactionWareConnectionFactoryProxy
  • JMS队列和JDBC是两种独立的事务资源。如本例所示,将jdbc事务管理器注入JMS适配器等同于使用ChainedTransactionManager(链接JMS事务管理器和jdbc事务管理器)

  • 有关
    TransactionWareConnectionFactoryProxy
    ,请咨询其JavaDocs:

     * Proxy for a target CCI {@link javax.resource.cci.ConnectionFactory}, adding
     * awareness of Spring-managed transactions. Similar to a transactional JNDI
     * ConnectionFactory as provided by a Java EE server.
     *
     * <p>Data access code that should remain unaware of Spring's data access support
     * can work with this proxy to seamlessly participate in Spring-managed transactions.
     * Note that the transaction manager, for example the {@link CciLocalTransactionManager},
     * still needs to work with underlying ConnectionFactory, <i>not</i> with this proxy.
    
    *目标CCI的代理{@link javax.resource.CCI.ConnectionFactory},添加
    *了解Spring管理的事务。类似于事务JNDI
    *由JavaEE服务器提供的ConnectionFactory。
    *
    *数据访问代码,应该不知道Spring的数据访问支持
    *可以使用此代理无缝地参与Spring管理的事务。
    *请注意,事务管理器,例如{@link CciLocalTransactionManager},
    *仍然需要使用底层ConnectionFactory,而不是此代理。
    
    我不确定这与您关于JMS+DB事务的请求有什么关系,但我认为您应该担心支持这两种事务资源的事务管理器

    为此,Spring建议对XA事务使用
    JtaTransactionManager
    。 或者可以考虑使用<代码> ChaneDeTraceActudioMeals<代码>基于Dave Syer文章:

    更新

    如果本地事务适合您,您确实可以继续使用
    TransactionWareConnectionFactoryProxy
    及其
    SynchedLocalTransactionLowed
    true
    。当然,也可以直接从
    中使用
    数据源TransactionManager


    否则,您必须使用
    ChainedTransactionManager
    。与第一个基于
    TransactionWareConnectionFactoryProxy的解决方案相比,此解决方案确实增加了一些开销。

    我浏览了Dave文章中的最佳jms db项目。它将DataSourceTransactionManager bean注入到jms:listener容器中(我将这个transactionManager注入到基于消息侦听器容器的消息驱动通道适配器中),但不使用任何JmsTransactionManager。我在这个项目或JTA事务管理器中看不到任何显式链接。在本例中,JMS事务资源和JDBC事务资源是如何同步的。请查看我在答案中的更新。谢谢,您是否可以建议这两种方法之间的区别-本地事务1PC(因此需要处理重复消息)而ChainedTransactionManager 2PCNo,
    ChainedTransactionManager
    也是1便士。只有在XA事务和JTA类似事务管理器的情况下,才有2PC。只有
    ChainedTransactionManager
    的问题是,您必须执行多个(几乎独立的)事务。您很高兴有了用于JMS的
    TransactionWareConnectionFactoryProxy
    。其他一些系统可能没有这样的解决方案,因此,
    ChainedTransactionManager
    将是一个答案。好的,除了重复消息处理部分之外,您在TransactionWareConnectionFactoryProxy方法中还看到了其他缺点吗。另外,如果我们需要像我前面的问题-[link]()中那样同步两个JMS事务资源,是否可以使用类似的TransactionWareConnectionFactory方法