Spring @事务性兔子侦听器导致无限循环
嗨,我的Rabbit侦听器有问题,它会导致无限循环异常(requeue消息)。我的配置看起来:Spring @事务性兔子侦听器导致无限循环,spring,rabbitmq,spring-rabbit,Spring,Rabbitmq,Spring Rabbit,嗨,我的Rabbit侦听器有问题,它会导致无限循环异常(requeue消息)。我的配置看起来: @Bean(name = "defContainer") public RabbitListenerContainerFactory containerFactory(ConnectionFactory connectionFactory, PlatformTransactionManager transactionManager){ SimpleRabbitListenerContainer
@Bean(name = "defContainer")
public RabbitListenerContainerFactory containerFactory(ConnectionFactory connectionFactory, PlatformTransactionManager transactionManager){
SimpleRabbitListenerContainerFactory containerFactory = new SimpleRabbitListenerContainerFactory();
containerFactory.setConnectionFactory(connectionFactory);
containerFactory.setConcurrentConsumers(5);
containerFactory.setAcknowledgeMode(AcknowledgeMode.AUTO);
containerFactory.setTransactionManager(transactionManager);
containerFactory.setMessageConverter(messageConverterAmqp());
containerFactory.setDefaultRequeueRejected(false);
return new TxRabbitListenerContainerFactory(containerFactory);
}
其中transactionManager是postgre db上事务的JpaTransactionManager。
TxRabbitListenerContainerFactory是我的工厂,它将setAlwaysRequeueWithTxManagerRollback设置为false:
public class TxRabbitListenerContainerFactory implements RabbitListenerContainerFactory {
private SimpleRabbitListenerContainerFactory factory;
public TxRabbitListenerContainerFactory(SimpleRabbitListenerContainerFactory factory) {
this.factory = factory;
}
@Override
public MessageListenerContainer createListenerContainer(RabbitListenerEndpoint endpoint) {
SimpleMessageListenerContainer container = factory.createListenerContainer(endpoint);
container.setAlwaysRequeueWithTxManagerRollback(false);
return container;
}
}
现在我有了listner,比如:
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "topic.two", durable = "true"),
exchange = @Exchange(value = "topic.def", type = "topic", durable = "true"),
key = "letter.*"
), errorHandler = "rabErrorHandler", containerFactory = "defContainer")
@Transactional
public Motorcycle topicLetters(Motorcycle motorcycle) throws Exception{
motorcycle.setId(UUID.randomUUID().toString());
Testing testing = new Testing();
testingRepository.save(testing);
throwEx();
return motorcycle;
}
其中方法throwEx()抛出未检查的异常。
数据库中的数据已正确回滚(未提交),但消息会不断重新查询,请在侦听器中查看:
@Bean
public RabbitListenerErrorHandler rabErrorHandler(){
return new RabbitListenerErrorHandler() {
@Override
public Object handleError(Message message, org.springframework.messaging.Message<?> message1, ListenerExecutionFailedException e) throws Exception {
System.out.println("FFFFFFFFFFF");
return null;
}
};
}
@Bean
公共RabbitListenerErrorHandler rabErrorHandler(){
返回新的RabbitListenerErrorHandler(){
@凌驾
公共对象handleError(Message Message,org.springframework.messaging.Message message1,ListenerExecutionFailedException e)引发异常{
System.out.println(“FFFFFFFFFFF”);
返回null;
}
};
}
如何预防无限循环,为什么会发生
编辑:
日志:在容器工厂上将
defaultRequeueRejected
设置为false
要以编程方式决定何时重新排队或不重新排队,请将其保留为true
,并在不希望重新排队时抛出AmqpRejectAndDontRequeueException
编辑
有点不对劲
protected void prepareHolderForRollback(RabbitResourceHolder resourceHolder, RuntimeException exception) {
if (resourceHolder != null) {
resourceHolder.setRequeueOnRollback(isAlwaysRequeueWithTxManagerRollback() ||
RabbitUtils.shouldRequeue(isDefaultRequeueRejected(), exception, logger));
}
}
如果两个布尔值都为false,则不重新求值。发现问题:
原因:由侦听器级别上指定的errorHandler处理程序引起。在某些情况下,错误处理程序返回null-这会导致无限循环(而不是重新引发异常和回滚事务)实际上我已经将containerFactory.setDefaultRequeueRejected(false);在工厂里。这就是为什么我不知道为什么它仍然是重播的原因。我还有一个修改过的工厂,它设置container.setAlwaysRequeueWithTxManagerRollback(false);在每个容器上,因为它需要设置,因为在这种情况下,tx被jpaTransactionManagerSorry抓取-错过了这一点;你用的是什么版本?能否附加显示循环的调试日志片段?另请参见我的编辑。