V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Canon1014
V2EX  ›  程序员

高并发场景下使用 CAS 锁库存,不预防 ABA 会怎么样

  •  
  •   Canon1014 · 2022-01-06 17:32:04 +08:00 · 2451 次点击
    这是一个创建于 1081 天前的主题,其中的信息可能已经有所发展或是发生改变。

    昨天一个帖子说道了 CAS 和 ABA,有个问题纠结一天了请教下各位大佬。

    我的理解是:ABA 问题无非就是库存从 10 变成 11 又变回 10 ,虽然后面的 10 已经不是我第一次查到的 10 了,但是库存无非就是个数字,只要库存数量合规合法直接扣不就好了

    所以如果不做预防措施会出现什么问题吗

    12 条回复    2022-01-08 16:59:09 +08:00
    ipwx
        1
    ipwx  
       2022-01-06 17:42:37 +08:00   ❤️ 1
    我觉得你对 CAS 锁的应用场景有些误区。库存这已经牵扯到业务数据库了,和 CAS 锁没有任何关系。

    要理解 CAS 中 ABA 的棘手难题,非得写几段 C++ 程序才有感觉。。。。这也是我为啥总是觉得学习东西不能用类比,用库存这种概念去理解高并发无锁的算法,总是不得要领。
    ipwx
        2
    ipwx  
       2022-01-06 17:43:57 +08:00
    ummm 想了想好像用在库存这种场景下倒也不是不可能。。。?
    wolfie
        3
    wolfie  
       2022-01-06 17:48:27 +08:00   ❤️ 1
    一直有个 modified_count 作为版本号,什么情况下会 ABA 。
    partystart
        4
    partystart  
       2022-01-06 17:55:30 +08:00   ❤️ 1
    所以有的 http 或者 rpc 接口会要求你提供一个幂等标识过去啊
    Chinsung
        5
    Chinsung  
       2022-01-06 17:58:35 +08:00   ❤️ 1
    个人感觉是 CAS 仅限于非常原子的操作,对上下文无依赖的那种。
    比如说,你前置条件是该商品上架状态才可以去减库存,此时你 CAS 保证了减库存,但不能保证自旋后之前的状态校验是正确的(当然你也可以加大自选范围,不过这样 CAS 也没什么优势了)。而锁可以保证。
    锁的底层一般也是依赖 CAS 去获取的
    zeni123
        6
    zeni123  
       2022-01-06 20:20:48 +08:00   ❤️ 1
    数据库的乐观锁也是用了类似 CAS 的实现 但是比 Java 里面的锁要复杂一下

    防止 ABA 只要加上版本号就可以 10v1.0 -> 11v1.1 -> 10v1.2 ....

    当然数据库用的是 MVCC 和 Java 里的不是太一样
    danieladu
        7
    danieladu  
       2022-01-07 09:46:33 +08:00   ❤️ 1
    CAS ,ABA , 包括数据库事务,都不是一个概念呀,防止 ABA ,就是在每次修改数据的时候,数据库记录 一个 tag (针对本次的修改),下次需要更新就检查带过来的 tag 和数据库的 tag 一致不一致,不一致说明中间已经被人修改了,就会拒绝本次更改。
    涉及到业务层就更加多样了。有些事直接返回用户错误,有些是传入一个委托,tag 不一致的时候重新获取一份新的数据,在这上面进行修改,等等等等。
    qiany
        8
    qiany  
       2022-01-07 10:02:40 +08:00   ❤️ 1
    这个和 countdownlatch 有点像 应该没啥问题
    exch4nge
        9
    exch4nge  
       2022-01-07 10:22:20 +08:00 via iPhone   ❤️ 1
    仅算库存数量场景没问题。有问题的场景是 CAS 的变量相关的东西发生改变。比如你还维护了这十个库存商品的唯一序列号之类的。实际场景下大部分 CAS 的是指针,指针没变但是由于内存分配器又复用了刚释放的位置,新分配的对象还是在一样的指针上,但是对象内容跟之前老的指针完全不一样
    exch4nge
        10
    exch4nge  
       2022-01-07 10:26:23 +08:00 via iPhone   ❤️ 1
    我还以为是原子操作 CAS ,是数据库 CAS ?不过都差不多
    qingshuang
        11
    qingshuang  
       2022-01-07 10:53:57 +08:00   ❤️ 1
    不是什么场景都要预防 ABA 问题的,扣减库存这种显然不用管 ABA 问题。
    如果有个接口需要判断库存是否发生过扣减,扣减了多少。这种情况需要考虑版本号
    Canon1014
        12
    Canon1014  
    OP
       2022-01-08 16:59:09 +08:00
    感谢各位的帮助,突然的开发任务没有及时回复表示抱歉 🙁
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   930 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 19:35 · PVG 03:35 · LAX 11:35 · JFK 14:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.