交易失败不重新排队
Don't requeue if transaction fails
我有一份配置如下的工作:
@Autowired
private ConnectionFactory connectionFactory;
@Bean
Step step() {
return steps.get("step")
.<~>chunk(chunkSize)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
@Bean
ItemReader<Person> reader() {
return new AmqpItemReader<>(amqpTemplate());
}
@Bean
AmqpTemplate amqpTemplate() {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setChannelTransacted(true);
return rabbitTemplate;
}
是否可以将 RabbitResourceHolder 的行为更改为在事务回滚时不重新排队消息?在 Spring 批处理中有意义吗?
在使用外部事务管理器时不是;回滚事务的全部意义在于将事情恢复到事务开始之前的状态。
如果您不使用事务(或仅使用本地事务 - 通过 setChannelTransacted(true)
而没有事务管理器),您(或 ErrorHandler
)可以抛出一个 AmqpRejectAndDontRequeueException
(或在容器上将 defaultRequeueRejected
设置为 false),消息将转到 DLQ。
我可以看出这是不一致的; RabbitMQ 文档说:
On the consuming side, the acknowledgements are transactional, not the consuming of the messages themselves.
所以 rabbit 本身不会重新排队交付,但正如您所指出的,资源持有者会这样做(但是当没有事务管理器并且我描述的 2 个条件之一为真时,容器将拒绝交付)。
我认为我们至少需要为您想要的行为提供一个选项。
我打开了AMQP-711.
我有一份配置如下的工作:
@Autowired
private ConnectionFactory connectionFactory;
@Bean
Step step() {
return steps.get("step")
.<~>chunk(chunkSize)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
@Bean
ItemReader<Person> reader() {
return new AmqpItemReader<>(amqpTemplate());
}
@Bean
AmqpTemplate amqpTemplate() {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setChannelTransacted(true);
return rabbitTemplate;
}
是否可以将 RabbitResourceHolder 的行为更改为在事务回滚时不重新排队消息?在 Spring 批处理中有意义吗?
在使用外部事务管理器时不是;回滚事务的全部意义在于将事情恢复到事务开始之前的状态。
如果您不使用事务(或仅使用本地事务 - 通过 setChannelTransacted(true)
而没有事务管理器),您(或 ErrorHandler
)可以抛出一个 AmqpRejectAndDontRequeueException
(或在容器上将 defaultRequeueRejected
设置为 false),消息将转到 DLQ。
我可以看出这是不一致的; RabbitMQ 文档说:
On the consuming side, the acknowledgements are transactional, not the consuming of the messages themselves.
所以 rabbit 本身不会重新排队交付,但正如您所指出的,资源持有者会这样做(但是当没有事务管理器并且我描述的 2 个条件之一为真时,容器将拒绝交付)。
我认为我们至少需要为您想要的行为提供一个选项。
我打开了AMQP-711.