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

Synchronizing JMS Message Queue and JDBC transaction- Is Transaction proxy needed

我们需要在事务中将消息从 JMS 队列持久保存到数据库,以确保在数据库持久保存期间抛出任何错误时 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 事务管理器)

对于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。当然,直接从 <int-jms:message-driven-channel-adapter>.

使用 DataSourceTransactionManager

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