※ 引述《life1347 (黑人)》之铭言:
: 就问题一的部分
: 从文章中的描述看起来是需要 strong data consistency
: 面对这种状况有种可行的做法是采用 distributed lock
: 但负面效益是会降低 throughput
: 流程大概是
: 1. user1 抢 write lock
: 2. user1 清除 cache & 更新 db
: 3. user2 发现 write lock 存在,用 watch 或 polling 方式
: 等待该 lock 消失 (设定 timeout),若消失就 r/w cache & db
: 4. user1 步骤 2
: 成功: db, cache 更新后,撤销 write lock
: 失败: 撤销 write lock 或 retry
: 由于无法假定步骤 4 一定会成功,因此要看错误状况来决定处理方式
: 目前想到两种可能作法
: 1. 撤销 write lock,让 user2 拿到旧资料。user1 返回错误看 application
: 怎么处理。这种状况以抢票例子来说,就是 user2 买到票而 user1 哭哭
: 2. 持续 retry 但设定 timeout,至少其他使用者不必持续等待
: 3. 若非 db 或 schema 异常,retry 直到成功为止。
: 但通常这种做法蛮糟糕的,会让多数使用者一直等待导致不耐
: 这边要看 business 选哪种做法对公司影响较小,没有绝对优劣
: 但通常在微服务架构(分布式系统)通常会采用 2
: 以上是个人经验,相信版上有其他更资深的大大有更好的观点可以讨论
user1 read
user1 下单抢座位001 and 得到订单处理中之讯息 (通常是icon转圈圈之类)
*user2 read
*user2 下单抢座位001 and 得到订单处理中
user1 得到交易成功
*user2 得到交易失败
通常不会用lock, 而是实际上整个流程都是read/write分离,做到transation like
async送出动作,callback得到结果
并且at-least-once:确保讯息有送达
量大需要scaling甚至是会有kafka之类的挂在中间
你也可以把上面event放在cache内,这样user2 read时其实可以显示位置正在被抢