分布式事务解决方案之RabbitMQ

本文讨论了分布式事务的问题,特别是在电商业务中,订单与库存服务间的协调。提出了RabbitMQ作为解决方案,包括可靠的发送和消费消息,以及消息的持久化。通过RabbitMQ的confirm机制、消息持久化、手动ACK、retry机制和messageID来确保事务的正确性和幂等性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分布式事务问题

以电商业务为例,订单服务对应的订单数据库,库存服务对应的库存数据库,多个数据源之间存在了分布式事务问题。如何保证在订单生成后,正确的扣除库存,或者在订单生成失败时,还原扣除的库存,这就是分布式事务将要解决的问题。

 

解决分布式事务前的业务逻辑:

@Transaction(rollbackFor=Exception.class)
public void createOrder(OrderInfo orderInfo) throws Exception {
    // 订单系统 —— 生成订单
    orderService.saveOrder(orderInfo);
    
    // 库存系统 —— 扣除库存
    if(!"success".equals(reduceStock(orderInfo))){
        throw new Exception("订单创建失败,原因:库存扣除失败!");
    }
}

上述存在的问题:

  • 库存服务的接口调用成功,订单数据库事务提交失败,库存没有回滚,导致订单生成失败但扣除了库存

  • 库存服务的接口调用超时,订单系统数据库事务被回滚,库存系统接口继续执行,导致订单生成失败但扣除了库存

Part3解决方案

生产者:订单系统将订单信息的消息发送到 RabbitMQ 中,消息到达交换机后通过 confirm 机制将接收成功的消息返回给订单系统(生产者),生产者收到正确的 confirm 后给用户返回订单创建成功的响应。

队列:为了防止 RabbitMQ 在收到消息后还未发送给消费者处理就挂了的情况,将队列和消息分别持久化。

消费者:消费者接收到消息后,为了确保消息能够被成功正确的处理,需要考虑消息丢失问题和消息幂等性等问题。

可靠的发送消息

在订单系统创建订单的事务中添加把消息保存到订单数据库的业务逻辑,将消息在生产者中持久化。

public class OrderDBService {
    public void createOrder(OrderInfo orderInfo) throws Exception {
        // 创建订单
        String sql = "...";
        int count = jdbcTemplate.insert(sql);
        if(count 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值