【问题标题】:Transaction handling while using message driven channel adapter & service activator使用消息驱动的通道适配器和服务激活器时的事务处理
【发布时间】:2012-11-08 00:26:47
【问题描述】:

我正在开发执行以下操作的 POC

  1. 使用消息驱动的通道适配器接收事务中的消息
  2. 调用服务激活器,该服务激活器使用处理程序将从适配器接收的消息插入到数据库,并将消息发布到出站通道。

现在,如果消息的 DB 插入失败,我希望 JMS 消息返回到队列,以便以后可以重试。

使用我的以下配置,它似乎不起作用。(即,即使在插入数据库时​​出现故障,消息也会从队列中删除。

任何指针或示例配置都会有所帮助。

<integration:channel id="jmsInChannel">         
    <integration:queue/>
</integration:channel>

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

<integration:service-activator input-channel="jmsInChannel"
    output-channel="fileNamesChannel" ref="handler" method="process" />

<bean id="handler" class="com.irebalpoc.integration.MessageProcessor">
    <property name="jobHashTable" ref="jobsMapping" />
</bean>

【问题讨论】:

    标签: jms distributed-transactions spring-integration


    【解决方案1】:

    设置 acknowledge="transacted" 并且,我认为 transactionManager 是 JDBC(或 JTA)事务管理器。

    您还需要从 JmsInChannel 中删除 ,以便数据库事务发生在同一个线程上。

    Spring 会将数据库事务与 JMS 事务同步。

    但是,请阅读 http://www.javaworld.com/javaworld/jw-01-2009/jw-01-spring-transactions.html 了解其含义。

    如果您不能使您的服务具有幂等性,您可能需要查看 XA 事务管理器。

    【讨论】:

    • 我认为您不需要(甚至可以)remove JmsInChannel -- 但您确实需要从中删除 queue。您需要一个 DirectChannel(默认值),它在同一线程上作为方法调用实现,因此其输出处理程序将在任何打开的事务中执行。 @Gary Russell -- 谢谢你的链接,这对我很有帮助。
    • @Gary Russell - 有没有办法在消息驱动通道适配器中设置重试时间?我试过recovery-interval="20000",但没有用
    • 我刚刚编辑了我的评论;我指定了 但没有转义字符,所以 html 吃掉了单词队列。
    • 恢复间隔是关于恢复连接的;与消息传递无关。消费者无法通过 JMS 告诉代理重试消息的频率;您可以在代理中设置一些内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-18
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多