事务处理Rabbit MQ和Spring AMQP

问题描述 投票:1回答:2

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

现在我的问题是这是如何工作的,这与2PC有何不同 - 以及什么情况可能会使用这种方法弄乱最终的一致性。令人惊讶的是,为什么我不必使用第三方jta。如果一切都很好 - 当我们使用春天的好东西使用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依赖

spring-transactions spring-amqp spring-rabbitmq distributed-transactions spring-rabbit
2个回答
5
投票

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

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

DB tx提交成功的可能性很小,但Rabbit tx回滚。这篇文章被称为“Best Effort 1PC”。您需要处理重复消息的可能性很小。

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


2
投票

关于“如何运作”的问题,spring-amqp文件中的这句话澄清了:

如果框架正在发送或接收消息时已有正在进行的事务,并且channelTransacted标志为true,则消息传递事务的提交或回滚将推迟到当前事务结束。如果channelTransacted标志为false,则没有事务语义适用于消息传递操作(它是自动执行的)。

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

© www.soinside.com 2019 - 2024. All rights reserved.