Spring integration Spring与JMS的集成和XA事务的条件回滚

Spring integration Spring与JMS的集成和XA事务的条件回滚,spring-integration,spring-jms,Spring Integration,Spring Jms,在通过MQ处理消息时,我希望有条件地回滚XA事务,并将MQ消息放回原始队列。 故障将被记录到数据库中,并可根据消息类型和错误使用自定义逻辑从数据库中重试。 如果我们不能将错误记录到数据库中,那么整个XA事务应该回滚,消息应该放回队列中。 每个消息都经过许多步骤处理,代码可以处理消息的重新提交/复制 我有一个解决方案,但它的结果是在丑陋的配置,我想知道是否有更好的方法来实现相同的结果? 我正在考虑使用一个链,如果消息出错,它将忽略该消息。 我讨厌服务激活器不是被调用的实际服务。有更好的方法吗

在通过MQ处理消息时,我希望有条件地回滚XA事务,并将MQ消息放回原始队列。
故障将被记录到数据库中,并可根据消息类型和错误使用自定义逻辑从数据库中重试。
如果我们不能将错误记录到数据库中,那么整个XA事务应该回滚,消息应该放回队列中。
每个消息都经过许多步骤处理,代码可以处理消息的重新提交/复制

我有一个解决方案,但它的结果是在丑陋的配置,我想知道是否有更好的方法来实现相同的结果? 我正在考虑使用一个链,如果消息出错,它将忽略该消息。
我讨厌服务激活器不是被调用的实际服务。有更好的方法吗


公共类自定义消息{
私人可丢弃的可丢弃的;
私有字符串原始消息;
私有布尔误差;
私有对象有效载荷;
}
公共类MessageServiceAdatperImpl{
@自动连线
私人第一阶段服务第一阶段服务;
@自动连线
私人第二阶段服务第二阶段服务;
//不要让失败回滚XA事务
@交易的
公共CustomMessage processFirstStage(CustomMessage CustomMessage){
试一试{
processFirstStage(customMessage.getPayload());
}捕获(可丢弃的e){
customMessage.setException(e);
}
返回自定义消息;
}
//不要让失败回滚XA事务
@交易的
公共CustomMessage processSecondStage(CustomMessage CustomMessage){
试一试{
processSecondStage(customMessage.getPayload());
}捕获(可丢弃的e){
markMessageInError(自定义消息,e)
}
返回自定义消息;
}
私有无效markMessageInError(CustomMessage CustomMessage,可丢弃的e){
customMessage.setThrowable(e);
customMessage.setInError(true);
}
}
公共类第一阶段服务(){
//启动新事务。代码还处理重复消息
@事务性(传播=传播。需要\u新建)
public void processFirstStage(){
//做些工作
}
}
公共类ErrorMessageProcessorImpl(){
私有静态最终标记fatal=MarkerFactory.getMarker(“fatal”);
@交易的
公共无效handleMessageError(CustomMessage CustomMessage){
if(customMessage!=null){
如果(customMessage.IsError()){
试一试{
//此时,执行将消息记录到数据库中的自定义逻辑。可以从中重新处理消息
//具有自定义重试限制的数据库,具体取决于消息类型和错误类型。
}
捕获(可丢弃的e){
//此时,回滚XA事务并将消息放回队列
logger.error(致命,String.format(“试图保存错误的致命错误”,e));
抛出新的RuntimeException(“试图保存错误的致命错误”,e);
}
}
}
}
}

既然您的逻辑与
MessageServiceAdatperImpl
非常接近,那么使用Spring集成(我的意思是
s)来避免这样的开销,只需在代码中执行
try…catch
if…else

从另一方面,您可以编写一个定制的通用
路由器
,它只通过内部逻辑返回通道名称


或者。。。不幸的是,自Spring Integration 4.1以来,我们不得不处理多种不同的消息类型。有几个不同的服务,一些消息流将重用,而其他消息流不会重用。我还希望流在配置中可见。我怀疑我会使用链,如果传入消息出错,我不会调用底层服务。这就是使用MDB并将对Spring Integration的调用包装在try catch中,这样我就可以在出现错误时控制MQ消息的重新提交。这就是为什么我建议
路由单张
,并查看下一节:
Process Manager企业集成模式
。您只有一个中央
RoutingSlipRouteStrategy
,它决定在哪里发送消息。您的配置应该更清晰。谢谢Artem,我想我将在消息驱动的通道适配器之后调用服务激活器。此服务将在新事务中调用新网关。如果返回的消息出错或返回了任何错误,则可以对其进行记录。如果此日志记录失败,服务将抛出异常,这将导致消息回滚。在配置上只有一个小的突破,其他的一切都会更干净。我应该先看看这个。谢谢你帮我想清楚。