Skip to content
功能特色定价方案合作伙伴博客帮助关于我们联系我们
免费开始登录
返回博客
guides2026-09-136 分钟阅读

多位服务员同一桌:订单层的冲突解决

4 位服务员同时编辑 20 人宴会桌时,last-write-wins 失效。来自安塔利亚度假村的乐观锁 + 409 Conflict 实战。

th

thMenu Team

thmenu.com

在安塔利亚 Belek 一场 1200 人份的宴会上,4 位服务员同时向同一张 20 人圆桌添加菜品。经典的 "last-write-wins" 会静默覆盖 14 道菜。下面介绍我们如何把乐观锁、409 Conflict 和重试模式落到生产。

为什么 last-write-wins 不够用

朴素的 UPDATE orders SET items = ? WHERE id = ? 只保留最后一次 commit。200 毫秒内 4 个 POST 进来,厨房只看到 6 道菜。

方案:每行加一列 version。客户端打开订单时读取,提交时回传,服务器做原子校验。

基于版本号的乐观锁

新增 version INTEGERupdated_at。PATCH 流程:

  • 客户端:{ items, expected_version: 7 }
  • 服务器:UPDATE ... WHERE id = ? AND version = 7
  • 影响 0 行 → 409 Conflict + 当前状态。

409 Conflict + 客户端合并

不做自动重试。客户端显示最新订单,高亮要新增/移除的项,等待用户确认。Belek 现场感知冲突率从 0.4% 降到 0%

再叠加 append-only 的 order_events 日志,谁、什么时间、做了什么都可审计。

常见问题

为什么不用 SELECT FOR UPDATE?它会序列化服务员,影响吞吐。

在 D1 上可用吗?可以,基于 INTEGER 的原子 UPDATE 不触发反模式。

离线呢?本地队列 + expected_version,重连时进入合并界面。

觉得有用?分享给朋友。