用 CAS 做库存或状态更新时,值改回原值会有什么风险?项目里怎么避免 ABA?
我的判断
ABA 的风险是值看起来回到原样,但中间发生过业务变化;库存和订单状态通常用版本号或单调状态规则解决。
比如订单状态从 INIT 变成 CANCELLED,又因补偿被写回 INIT。另一个线程只比较当前值,会以为从未变化,继续执行一段基于旧前提的逻辑。内存结构可以用 AtomicStampedReference,把值和版本一起 CAS。
数据库里更常见的是乐观锁:
UPDATE orders
SET status = ?, version = version + 1
WHERE id = ? AND version = ?;
状态机如果本身只能单向流转,也会把合法前置状态写进 WHERE,拒绝倒退。消息消费再用事件 ID 或业务请求号幂等,不能只依赖状态值。
简单库存数字从 10 变 9 再回 10 是否有风险,要看业务是否关心中间过程;不关心就没必要为了术语增加版本。先找被破坏的不变量,再决定是否需要防 ABA。