从单体到微服务,数据一致性这道坎怎么迈?

从单体到微服务,数据一致性这道坎怎么迈? 单体架构时数据一致性根本不是问题。一个本地事务Transactional注解一加要么全成功要么全回滚简单粗暴。可一旦拆成微服务每个服务独立数据库一个业务操作跨多个服务本地事务直接失效。订单创建了库存没扣支付成功了订单状态没更新——数据不一致的坑几乎每个团队都踩过。这道坎的本质是分布式事务问题。CAP理论告诉我们分区容忍性必须保证的前提下一致性和可用性只能二选一。微服务架构下强一致性代价极高所以BASE理论成了主流基本可用、软状态、最终一致。换句话说我们追求的不是“时刻一致”而是“最终一致”。那具体怎么落地常见方案有几种各有适用场景。2PC/3PC两阶段提交数据库层面支持但性能差、阻塞严重微服务场景基本不用。TCCTry-Confirm-Cancel业务侵入大每个操作都要写三个方法适合金融等高一致性场景但开发成本高。Saga把长事务拆成多个本地事务每个事务有补偿操作适合业务流程长、一致性要求相对宽松的场景。本地消息表是目前中小团队最常用的方案业务操作和消息写入放在同一个本地事务然后异步投递消息下游消费成功后更新状态失败则重试。事务消息如RocketMQ把消息投递和本地事务绑定实现最终一致省去本地消息表的维护但依赖特定MQ。实际项目中我推荐优先考虑本地消息表定时补偿。它不依赖特殊中间件实现简单可控性强。具体做法在订单库中建一张消息表创建订单和插入消息在同一个事务里。然后有个定时任务扫描消息表投递到MQ下游消费后回调确认。如果消费失败定时任务会重试直到成功。配合幂等设计基本能解决80%的跨服务一致性问题。但比技术方案更重要的是业务设计。很多分布式事务问题其实是领域边界没划清。比如订单和库存如果强行拆成两个服务每次下单都要跨服务扣库存一致性自然难保。更好的做法是把强关联的业务放在同一个服务里或者通过聚合根设计让一个服务拥有完整的数据主权。能避免分布式事务就尽量避免。另外幂等和重试是最终一致性的基石。下游服务必须保证同一个消息多次消费结果一致通常用唯一业务ID去重表实现。重试策略要设置上限和退避避免雪崩。最后监控和补偿不能少。最终一致性意味着中间状态可能持续一段时间必须有对账机制定期核对核心数据发现不一致自动修复或告警。从单体到微服务数据一致性这道坎迈过去的关键不是追求强一致而是接受最终一致用合适的方案清晰的领域边界完善的补偿机制把不一致控制在可接受范围内。没有银弹但有一套组合拳。记住能不分库就不分库能本地事务就别分布式事务。架构是演进而非一步到位数据一致性也是如此。