我的要求是使用事务会话与消息驱动通道适配器(JmsMessageDrivenEndpoint) . 我可以使用sessionTransacted = true为DefaultMessageListenerContainer设置配置购买 .
工作流程:接收消息 - >调用服务激活器 - >服务激活器调用dao类
在成功提交数据库时,spring框架调用commit(),并且在任何运行时异常上,spring框架都会调用rollback() . 哪个工作得很好 . 发生回滚时,JMS代理会再次将消息发送回我的应用程序 .
对于dao中的特定类型的异常,我想添加一个消息头(即重新传递时间),以便JMS Broker不会立即再次发送消息 . 我该怎么做?
对于dao中的另一种特定类型的异常,我想使用控制总线来停止终点(消息驱动通道适配器),并在停止之前回滚前一个事务 . 我该怎么做?
任何人都可以帮助我吗?
3 回答
毫无疑问,如何使用Control Bus作为启动/停止 endpoints :
或者您可以从代码的任何位置向
controlChannel
发送相同的命令字符串 .但是最后一笔交易将被回滚并不重要 . 这取决于您的“工作单位”(换句话说 - 您的服务行为) .
但是,您可以在发送'stop command'的同时标记当前事务以进行回滚:
关于“添加一些邮件 Headers ”的另一个问题对于Messaging来说是不正常的 . 如果您更改了消息,它将是一个新消息,您无法使用一些新信息将消息回滚到队列 .
当然,无论如何你都可以做到并有新的信息 . 但你应该
resend
它,而不是回滚 . 所以,你应该提交事务并将新消息发送到某个地方(或者发送到同一个队列),但对于你的应用程序来说,它将是Broker的新消息 . 还有一次:对于这种情况,你必须提交交易 .不确定它是非常清楚的,我在我的asnwer中正确的方式,但希望它有点帮助你 .
在回滚之前,您无法修改消息(添加标头) . 当然,您可以在捕获异常后将其重新排列为新消息 . 某些代理(例如ActiveMQ)在回滚后提供退避重试策略 . 如果您的经纪人支持,这可能是更好的解决方案 .
您可以使用控制总线来停止容器,但您可能必须异步执行(在另一个线程上调用停止,例如在控制总线上使用
ExecutorChannel
) . 否则,根据您的环境,您可能会遇到停止等待容器线程退出的问题,因此您不应该在容器线程本身上执行停止 .最好的办法是实验 .
谢谢Gary和Artem . 解决方案正在发挥作用我使用以下配置:
现在我的问题是,如果我想要停止多个入站适配器,我如何向所有这些适配器的控制总线发送单个消息?
我要去研究SpEL . 如果有人已经知道,我将不胜感激 .
谢谢