Spring集成:从JMS读取 - >处理消息 - >坚持数据库

时间:2017-05-17 13:37:56

标签: spring jms spring-integration persistence

我使用Spring Integration从JMS读取消息,处理它们然后使用我自己的dbPersistor的persist方法将它们持久化到数据库,该方法的返回类型为void。我编写了一个测试用例来验证发布到JMS的消息是否已成功保存在db中。此测试的我的SI和JMS配置如下 -

<int:poller fixed-delay="500" default="true"/>

<int:channel id="inputChannel">
    <int:queue/>
</int:channel>
<int:channel id="errorChannel">
    <int:queue/>
</int:channel>
<jms:message-driven-channel-adapter id="jmsInboudAdapter"         
   connection-factory="connectionFactory" destination-name="MessageQueue" 
   channel="inputChannel" error-channel="errorChannel" transaction-manager="dbTxManager"                                    
   acknowledge="transacted"/>

<int:chain id="handlerChain" input-channel="inputChannel">
    <int:service-activator ref="jmsMessageHandler" method="handleMessage" />
    <int:service-activator ref="dbPersistor" method="persist" />   
</int:chain>

然后在测试中我执行以下操作 -

  • jmsTemplate.send()
  • verifyMessageWasPersistedToDB

当我向数据库发布单个消息时,这很有用。但是当我循环遍历jmsTemplate.send()以发布多个消息时,主线程在SI线程仍在执行时完成操作并尝试验证DB中的消息并因为某些消息尚未保留而失败。我的问题是 -

  1. 如何让主线程等待SI线程完成然后调用verify方法?
  2. 如果出现数据库异常和回滚,如何验证失败的邮件是否已返回原始队列?
  3. 由于 AJ

1 个答案:

答案 0 :(得分:0)

  1. inputChannel不应该是队列通道 - 当消息插入队列时,JMS事务将提交 - 不会在JMS事务的范围内执行DB事务。您必须使用直接通道(删除轮询器和<queue/>)。请参阅the documentation on transactions in Spring Integration

  2. 您必须轮询数据库以获得结果;你可能会添加一个拦截器和一些CountDownLatch,但只是轮询数据库直到结果出现或一段时间到期为止。