Java JMS消息排序和事务回滚
我们正在构建一个系统,该系统将通过JMS从一个应用程序向另一个应用程序发送消息(如果需要的话,使用Websphere MQ)。这些消息的形式为“创建x”或“删除x”。(这样做的最终结果是需要将创建和删除消息通知第三方系统,因此JMS队列的读取端将与第三方系统通信,而JMS队列的写入端只是将要处理的消息广播出去) 我们在这里担心的问题是,如果其中一条消息失败。这里最初的想法只是将故障回滚到JMS队列,并让正常的重试机制处理它。这将一直有效,直到您获得一个删除,然后为同一标识符创建,例如Java JMS消息排序和事务回滚,java,jms,ibm-mq,Java,Jms,Ibm Mq,我们正在构建一个系统,该系统将通过JMS从一个应用程序向另一个应用程序发送消息(如果需要的话,使用Websphere MQ)。这些消息的形式为“创建x”或“删除x”。(这样做的最终结果是需要将创建和删除消息通知第三方系统,因此JMS队列的读取端将与第三方系统通信,而JMS队列的写入端只是将要处理的消息广播出去) 我们在这里担心的问题是,如果其中一条消息失败。这里最初的想法只是将故障回滚到JMS队列,并让正常的重试机制处理它。这将一直有效,直到您获得一个删除,然后为同一标识符创建,例如 Dele
- Delete 123-失败,回滚到队列
- 创建123-成功
- 删除123-从早期故障重试
编辑-进一步复杂化。我们正在构建的与第三方集成的系统将取代他们最近从不同供应商处使用的系统。因此,第三方中已经存在大量数据,但实际上很难获取这些数据。(第三方甚至不发送成功/失败消息,只是确认接收!),因此我们实际上不知道系统的初始状态 避免上述情况的一种方法是对消息故障进行不同的分类;请记住,您的邮件应该按顺序处理。(邮件关联) 考虑场景:- 如果应用程序接收到删除X,但之前未接收到创建X, 然后将此错误场景分类为“
业务错误”
,因为发生此错误是因为
消息的生产者发送了错误消息。或者我们可以说消息的生产者以错误的顺序发送消息
一旦您将此错误分类为“业务错误”
”,就不应该调用回滚;而不是将此消息插入数据库,并以“业务错误”作为标识
所以,通过这种方式,您可以从队列提交此消息,降低回滚风险,并进一步降低应用程序行为不一致的风险
现在考虑另一种情况:-
如果您的应用程序本身存在一些问题(例如,数据库或web服务器出现故障或任何此类技术错误),那么在这种情况下,请使用JMS队列的回滚机制,并将此错误视为“技术错误”
”
所以,若出现任何“技术错误”
,JMS队列将重试该消息,直到您的应用程序能够接受并处理这些错误
一旦您的应用程序在出现此“技术错误”
”后启动,并尝试按顺序处理消息,此处应用的规则相同,即如果发生“业务错误”,则不再重试该消息
注意:“业务错误”分类应得到各方的同意,即,如果您将任何消息标记为“业务错误
”,则表示此消息不再有用,您的制作人应为任何有效的“创建x”发送新的“删除x”
您可以考虑的一些“业务错误”包括--
避免上述情况的一种方法是对消息失败进行不同的分类,请记住,应该按顺序处理消息。(消息关联) 考虑场景:- 如果应用程序接收到删除X,但之前未接收到创建X, 然后将此错误场景分类为“
业务错误”
,因为发生此错误是因为
消息的生产者发送了错误的消息。或者我们可以说消息的生产者以错误的顺序发送消息
一旦您将此错误分类为“业务错误”
”,您就不应该调用rollback;而是将此消息插入数据库,并以“业务错误”作为标识
所以,通过这种方式,您可以从队列提交此消息,降低回滚风险,并进一步降低应用程序行为不一致的风险
现在考虑另一种情况:-
如果您的应用程序本身存在一些问题(例如,数据库或web服务器出现故障或任何此类技术错误),那么在这种情况下,请使用JMS队列的回滚机制,并将此错误视为“技术错误”
”
所以,若出现任何“技术错误”
,JMS队列将重试该消息,直到您的应用程序能够接受并处理这些错误
一旦您的应用程序在出现此“技术错误”
”后启动,并尝试按顺序处理消息,此处应用的规则相同,即如果发生“业务错误”,则不再重试该消息
注:“业务错误”分类应经各方同意,即