我尝试使用JPATransactionManager运行骆驼transacted()路由(独立的Java进程)是spring PlatformTransactionManager(因为我希望骆驼路由在单个DB事务中运行),但是我无法禁止从MQ重新交付即使我在onException子句中使用了handle(true)以及我的自定义重新交付策略(成功执行),如果交易方法失败,也将代理。我只希望在服务崩溃时重新交付MQ。
在下面尝试过,但不起作用:
重新运输骆驼,然后处理(true)。
onException(Exception.class)
.log("ERROR OCCURRED")
.redeliveryPolicyRef("myRedeliveryPolicy")
.handled(true)
.to(getPostExceptionRoute());
@Bean
@Autowired
public RedeliveryPolicy myRedeliveryPolicy() {
RedeliveryPolicy myRedeliveryPolicy= new RedeliveryPolicy();
myRedeliveryPolicy.setMaximumRedeliveries(2);
myRedeliveryPolicy.setMaximumRedeliveryDelay(2000);
return myRedeliveryPolicy;
}
@Bean
@Autowired
public JmsComponent jms(IJMSConnectionFactory cf) throws JMSException {
JmsComponent jmsComponent = new JmsComponent();
jmsComponent.setConfiguration(jmsConfig(cf));
jmsComponent.setTransacted(false);
return jmsComponent;
}
from("jms:queue:TestQueue?acknowledgementModeName=CLIENT_ACKNOWLEDGE")
.unmarshal().json(JsonLibrary.Jackson, TestObject.class)
.transacted()
.processRef("myPersistInDBProcessor")
我希望骆驼按照重新交付策略(有效)尝试重新交付,但是MQ不应该重新交付。
答案 0 :(得分:0)
我希望骆驼按照重新交付政策(有效)尝试重新交付,但MQ不应该重新交付
当MQ 绝不能进行重新交付时(因为您处理了Camel中的错误),应删除acknowledgementModeName=CLIENT_ACKNOWLEDGE
或显式设置AUTO_ACKNOWLEDGE
(默认值)。
只要未确认消息,就不会从代理角度传递消息。 AUTO_ACKNOWLEDGE
在消费后立即确认该消息,这对于您从不不希望再次交付您是有意义的。
CLIENT_ACKNOWLEDGE
仅在特定条件下确认消息,请参见this post for some more info about this。
如果您希望MQ重新交付,但在大多数情况下用Camel“覆盖”它们,则必须使用已处理的消息。
通过这样配置您的JMS组件使用本地JMS代理交易
jmsComponent.setLazyCreateTransactionManager(false);
jmsComponent.setTransacted(true);
对于这种类型的事务,您根本不需要Spring TransactionManager。因此,我猜想JPATransactionManager
被JMS忽略了,并且您的JMS使用量应该是事务性的。
现在,当您的骆驼错误处理程序通过使用handled(true)
“吞下”一个异常时,必须没有MQ重新交付。但是,当将异常传播回代理时,MQ会重新交付。
我希望我的骆驼路线可以在单个数据库事务中运行
在您的问题中,我没有找到有关无法正常工作的数据库事务的任何信息。似乎只有一个处理数据库的处理器。如果这不能正常工作,请在您的问题或单独的问题中描述问题。
答案 1 :(得分:0)
根据Apache Karaf Transaction Guide,doTry和doCatch应该按预期工作。在您的情况下,可能是异常触发了错误情况。只有checked exceptions(没有RuntimeException或其后代)不会将正在进行的事务标记为回滚。