事务处理 Rabbit MQ 和 Spring AMQP

Transaction handling Rabbit MQ and Spring AMQP

我想在这里了解一些事情。我的要求是我想将记录存储在数据库中并想将消息发送到队列,然后如果它抛出一些异常我不想发送消息也不想提交数据库事务,那么让我们用相同的方法说。 现在我想到了使用 spring 事务,但是由于两种不同的资源,我想到了使用 JTA 使用一些 atomikos 来同步资源 - 但我再次阅读 RMQ 不支持 2PC 或 XA 等。 无论如何,我继续尝试先尝试不添加 atomikos,我所做的只是确保我的频道进行了交易并且 @Transaction 注释得到了照顾,请参阅下面的示例代码 - 我没有在 pom 中添加任何特殊内容。

现在我的问题是它是如何工作的,它与 2PC 有何不同 - 方法可能出现什么问题以及使用这种方法在什么情况下会破坏最终的一致性。令人惊讶的是,为什么我不必使用第三方 jta。如果这一切都很好 - 在我看来,当我们使用 spring 好东西使用 rmq 和 db 时,这似乎是最终的一致性保证!对于微服务:)

如果这不是好的解决方案,还有哪些替代方案 - 如果可能的话,我想避免工作进程等,以实现最终的一致性。

@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
    rabbitTemplate.setChannelTransacted(true);
    return rabbitTemplate;
}

@GetMapping
@Transactional
public void sampleEndpoint(@RequestParam boolean throwException){
    Customer a=new Customer();
    a.setCustomerName("XYZ");
    customerRepository.save(a);
    rabbitTemplate.convertAndSend("txtest","Test");
    if(throwException)
    throw new RuntimeException();
} 

我使用 spring boot 1.5.7

在上面的示例中使用了 postgres 依赖项

我建议你阅读 Dave Syer's article: Distributed transactions in Spring, with and without XA

您需要在数据库事务之前启动 Rabbit 事务,以便 rabbit 事务与数据库事务同步并在数据库 tx 之后很快提交,如果数据库 tx 回滚则回滚。

有小概率DB交易提交成功,但Rabbit交易回滚。这在文章中被称为"Best Effort 1PC"。您需要处理重复消息的可能性很小。

您没有显示所有配置,但看起来您的 Rabbit 交易会在数据库之前提交,这可能不是您想要的。

关于 "How is it working" 问题,spring-amqp 文档中的这句话澄清了:

If there is already a transaction in progress when the framework is sending or receiving a message, and the channelTransacted flag is true, then the commit or rollback of the messaging transaction will be deferred until the end of the current transaction. If the channelTransacted flag is false, then no transaction semantics apply to the messaging operation (it is auto-acked).

我的理解是,对于您的用例,您甚至不需要配置 ChainedTransactionManager 来实现 Best Effort 1PC。 @Transactional 就足够了,兔子 tx 将在 DB tx 之后立即提交。