同一事务中的出站通道适配器

时间:2016-04-25 20:26:42

标签: java spring spring-integration

我有一个场景,其中两个jms出站通道适配器从pub-sub通道读取,我希望它们参与一个事务。换句话说,我想把信息写给他们两个或没有。即使我将会话交易设置为true,但似乎并未发生。这是我的配置:

<int:publish-subscribe-channel id="test.pubsub" ignore-failures="false" ></int:publish-subscribe-channel>



        <jms:outbound-channel-adapter channel="test.pubsub" order="1" destination-name="${outbound.queue}" session-transacted="true"
             connection-factory="${connection.factory}"></jms:outbound-channel-adapter>

        <jms:outbound-channel-adapter id="jmsOutputMirror" session-transacted="true"
                    destination-name="${outbound.queue.mirror}"
                    connection-factory="${connection.factory}"
                     channel="test.pubsub" order="2">
        </jms:outbound-channel-adapter>

他们都从CachingConnectionFactory获得连接。

1 个答案:

答案 0 :(得分:2)

session-transaction对您没有帮助:

/**
 * Set the transaction mode that is used when creating a JMS {@link Session}.
 * Default is "false".
 * <p>Note that within a JTA transaction, the parameters passed to
 * {@code create(Queue/Topic)Session(boolean transacted, int acknowledgeMode)}
 * method are not taken into account. Depending on the Java EE transaction context,
 * the container makes its own decisions on these values. Analogously, these
 * parameters are not taken into account within a locally managed transaction
 * either, since the accessor operates on an existing JMS Session in this case.
 * <p>Setting this flag to "true" will use a short local JMS transaction
 * when running outside of a managed transaction, and a synchronized local
 * JMS transaction in case of a managed transaction (other than an XA
 * transaction) being present. This has the effect of a local JMS
 * transaction being managed alongside the main transaction (which might
 * be a native JDBC transaction), with the JMS transaction committing
 * right after the main transaction.
 * @see javax.jms.Connection#createSession(boolean, int)
 */
public void setSessionTransacted(boolean sessionTransacted) {
    this.sessionTransacted = sessionTransacted;
}

如果你对它们的调用都没有包装到TX。既然你很幸运并且在同一个线程中调用了两个适配器,那么只需要将发送到test.pubsub的消息包装到TX中。例如该频道前面有一些@Transactional @Gateway。或任何其他可能的<tx:advice>挂钩。您甚至可以考虑这个解决方案:Keep transaction within Spring Integration flow