0

有一个抢红包场景更新红包的剩余数量和剩余金钱,
是使用类似cas的更新还是先select for update性能高?
不管哪种方式在update那一步会等待,cas感觉会有很多无效更新尝试。
参考的文档地址: url

while (hadHongBao()) {
    //剩余红包个数
    def remainCount = getRemainCount() 
    //实时计算获取红包金额
    def getAmount = calculateAmount() 
    def result = sql.excute("update '红包计算表' set balance=${total-getAmount}, remainCount=${remainCount-1} where remainCount=${remainCount} and id=${id}")
    // 更新失败既继续执行循环,直到更新成功或已领取完,达到CAS效果
    if (result > 0) {
        // 更新成功,执行更新缓存等后续操作
        // ......
        break
    }
}

语句

 update window_red_pack
     set remain_price=#{remainPrice}, remain_num=#{remainNum}
     where id=#{redPackId} and  remain_price=#{expectedPrice} and  remain_num=#{expectedNum}

1个回答

0

阿里巴巴的开发规范上提到,在并发不高的情况下(尝试失败率不超过20%的情况下),推荐用cas更新。

如果MySQL用InnoDB引擎的话(UPDATE会用行锁),几乎很难碰到尝试失败的情况(除非某种表就只有没几行,但又是被频繁更新的)。(这也反映了并发编程Debug和Test的困难,但也有些技巧,比如故意在同一时刻开很多线程对同一行做更新。)

撰写答案