【问题标题】:Synchronizing JMS Message Queue and JDBC transaction- Is Transaction proxy needed同步 JMS 消息队列和 JDBC 事务 - 是否需要事务代理
【发布时间】:2017-07-17 02:45:26
【问题描述】:

我们需要在事务中将消息从 JMS 队列持久化到数据库,以确保在 DB 持久化期间抛出任何错误时不会确认 JMS 消息。 基于此处提供的解决方案-Transaction handling while using message driven channel adapter & service activator 以下是我到达的方法

<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>

请确认理解是否正确。另外,有以下疑问

  1. 在这种情况下是否需要 TransactionAwareConnectionFactoryProxy
  2. JMS 队列和 JDBC 是两个独立的事务资源。将 jdbc 事务管理器注入到 JMS 适配器中,如本例所示,相当于使用 ChainedTransactionManager(链接 JMS 事务管理器和 JDBC 事务管理器)

【问题讨论】:

    标签: spring-integration spring-jms


    【解决方案1】:

    对于TransactionAwareConnectionFactoryProxy,请查阅其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.
    

    我不确定这与您对 JMS+DB 事务的请求有何关系,但我认为您应该担心支持这两种事务资源的事务管理器。

    为此,Spring 建议使用 JtaTransactionManager 进行 XA 事务。 或者你可以根据 Dave Syer 的文章考虑使用ChainedTransactionManagerhttp://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html

    更新

    如果本地交易适合您,您真的可以继续使用TransactionAwareConnectionFactoryProxy 及其synchedLocalTransactionAllowedtrue。当然,直接从&lt;int-jms:message-driven-channel-adapter&gt; 使用DataSourceTransactionManager

    否则你必须使用ChainedTransactionManager。这个解决方案确实比第一个基于 TransactionAwareConnectionFactoryProxy 的解决方案增加了一些开销。

    【讨论】:

    • 我浏览了 Dave 文章中的 best-jms-db 项目。它将 DataSourceTransactionManager bean 注入 jms:listener-container(我将此 transactionManager 注入基于消息侦听器容器的消息驱动通道适配器)但不使用任何 JmsTransactionManager。我在这个项目或 JTA 事务管理器中看不到任何显式链接。本例中 JMS 事务资源和 JDBC 事务资源是如何同步的。
    • 请看一下我在答案中的更新。
    • 谢谢,您能否提出两种方法之间的区别 - 是本地事务 1PC(因此需要处理重复消息)而 ChainedTransactionManager 2PC
    • 不,ChainedTransactionManager 也是 1PC。只有在 XA 事务和类似 JTA 的事务管理器的情况下,您才有 2PC。只有ChainedTransactionManager 的问题是您必须执行多个(几乎独立的)事务。您很高兴有用于 JMS 的 TransactionAwareConnectionFactoryProxy。其他一些系统可能没有这样的解决方案,所以ChainedTransactionManager 将是一个答案。
    • 好的,除了重复的消息处理部分之外,您在 TransactionAwareConnectionFactoryProxy 方法中看到的任何其他缺点。另外,如果我们需要像我之前的问题一样同步两个 JMS 事务资源,是否可以使用类似的 TransactionAwareConnectionFactoryApproach-[link](stackoverflow.com/questions/42441359/…)
    猜你喜欢
    • 2012-03-03
    • 2018-10-24
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 2015-11-27
    • 2019-09-18
    相关资源
    最近更新 更多