知用网
第二套高阶模板 · 更大气的阅读体验

微服务治理中的事务处理:让系统协作更稳

发布时间:2025-12-18 06:00:54 阅读:299 次

你点个外卖,从下单到骑手接单,背后可能涉及订单、支付、库存、配送等多个服务。这些服务各自独立运行,就像一个个小团队分工合作。可一旦中间出问题,比如钱扣了但订单没生成,用户肯定炸锅。这时候,怎么保证多个服务之间的操作要么全成功,要么全失败?这就是微服务里的事务处理要解决的事。

传统事务不灵了

以前单体应用里,所有功能都在一个程序里,数据库也只有一个。下个订单,扣库存、写订单记录,用数据库的事务就能搞定——BEGIN TRANSACTION,出错就ROLLBACK,简单直接。

可到了微服务,每个服务都有自己的数据库,订单服务管订单库,库存服务管库存库。这时候再想“一起提交”,数据库层面的事务已经跨不动了。好比你不能让两家银行同时锁账户转账,还得确保两边都不出错。

分布式事务的常见解法

面对这种跨服务的操作,得靠一些新办法来协调。

2PC(两阶段提交) 是个经典思路。它像开会投票:第一阶段问大家“准备好了吗”,都同意才进入第二阶段“正式提交”。虽然能保证一致性,但流程长,中间卡住容易阻塞,性能差,实际在高并发场景很少用。

现在更多人用 最终一致性 + 补偿机制。典型代表是 TCC(Try-Confirm-Cancel)

还是拿下单举例:

  • Try 阶段:先冻结库存和用户余额,相当于预扣;
  • Confirm 阶段:都准备好了,正式扣减;
  • Cancel 阶段:中间任何一个环节失败,就把之前冻结的释放掉。

这种方式不追求实时一致,但保证最终状态是对的,更适合微服务环境。

用消息队列实现可靠事件

还有一种常见做法是通过消息队列来驱动事务。比如用户下单成功后,发一条“订单创建”消息到MQ,库存服务消费这条消息去扣库存。万一扣失败,消息还能重试,甚至告警人工介入。

关键是要保证“发消息”和“本地操作”一起成功或失败。常用做法是把消息暂存本地表,等订单写入数据库后再异步发送,避免消息发了但订单没落库。

服务治理平台的作用

光有技术方案还不够,微服务多了以后,谁调谁、调用成功率、超时重试,全得靠治理平台来管。像阿里开源的 Nacos 或 Spring Cloud Alibaba 这类工具,能帮你做服务发现、熔断限流、链路追踪。

比如某个服务频繁超时,治理平台可以自动熔断,防止雪崩;或者看到事务相关接口错误率上升,立刻告警排查。

代码示例:简单的补偿逻辑

下面是个简化版的补偿事务示意:

public class OrderService {

    public boolean createOrder(Order order) {
        // 1. 创建订单
        if (!orderDao.save(order)) {
            return false;
        }

        // 2. 调用库存服务扣减
        boolean deducted = inventoryClient.deduct(order.getProductId(), order.getCount());
        if (!deducted) {
            // 扣减失败,触发补偿:删除刚创建的订单
            orderDao.delete(order.getId());
            return false;
        }

        return true;
    }
}

虽然简单,但它体现了“出错就反向操作”的补偿思想。真实场景会更复杂,可能要用到事务消息或专门的框架如 Seata。

微服务的事务处理,本质是在分布式环境下重新定义“可靠”。没有银弹,只有根据业务特点选择合适模式,再靠治理工具兜底,才能让系统既灵活又稳当。