“非事务性系统?是的,可以实现一致性(无需崩溃)”——萨迦模式、发件箱和幂等性指南

发布日期:2026-07-23 10:00:53  浏览量 :0
发布日期:2026-07-23 10:00:53  
0

🧠 经典难题:你已不再身处关系型数据库之中

还记得那段美好的时光吗?那时你只需加上一个 @Transactional 注解,一切便皆大欢喜。要么提交,要么回滚,绝无中间状态。然而,世界决定转向微服务、非关系型数据库、消息队列和事件驱动架构……于是,那种严格的原子性、一致性、隔离性和持久性(ACID)特性便荡然无存。

当您需要确保多个分布式操作以一致的方式执行,却又没有一个统一的数据库来协调这一切时,该怎么办呢?

答案包含四个字母:BASE(基本可用性、软状态、最终一致性)。在实践中,这转化为:

  • 萨加模式(编排或协同)
  • 补偿机制(即所谓的手动回滚)
  • 幂等性(防止重复操作造成混乱)
  • 事务发件箱(防止消息丢失)
  • 状态/日志表(用于追踪每个萨加流程的当前状态)

让我们通过代码示例(模拟一个相当棘手的电子商务系统)来详细解析每一项。

1️⃣ 萨加模式 – 将大型事务拆分为小型片段

这个理念非常美妙:与其尝试执行一个涵盖多个服务的巨大 COMMIT(提交)操作,不如将操作分解为多个小型本地事务,每个事务都有其各自的操作以及相应的补偿操作(以防出现错误)。

orchestrate(编排)萨加流程有两种方式:

🎭 协同(每个服务各司其职并发布事件)

没有中心化的流程控制。每个服务监听事件并做出反应。

// 订单服务
public void 创建订单(订单命令 命令) {
    订单仓库.保存(命令);  // 本地事务
    事件总线.发布(new 订单已创建事件(命令.获取标识(), 命令.获取客户标识()));
}

// 支付服务(监听 订单已创建事件)
@事件监听器
public void 处理支付(订单已创建事件 事件) {
    try {
        支付服务.授权(事件.获取客户标识(), 事件.获取金额());
        事件总线.发布(new 支付已授权事件(事件.获取订单标识()));
    }

免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。

分享到:

长按或扫码识别 分享给好友

长按或扫码识别 分享给好友
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据