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

时间:2017-02-26 14:18:55

标签: spring-integration spring-jms

我们需要将消息从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 Queue和JDBC是两个独立的事务资源。将jdbc事务管理器注入到JMS适配器中,如此示例所示,等效于使用ChainedTransactionManager(链接JMS事务管理器和JDBC事务管理器)

1 个答案:

答案 0 :(得分: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 +数据库事务的请求有什么关系,但我认为您应该担心支持这些事务资源的事务管理器。

为此,Spring为XA事务建议JtaTransactionManager。 或者,您可以根据Dave Syer文章http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html

考虑使用ChainedTransactionManager

<强>更新

如果本地交易对你没用,你真的可以继续使用TransactionAwareConnectionFactoryProxy及其synchedLocalTransactionAllowedtrue。当然,直接从DataSourceTransactionManager使用<int-jms:message-driven-channel-adapter>

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