利用redis的单线程特性
setnx (SET if Not eXists) 命令在指定的 key 不存在时,为 key 设置指定的值。
getset 自动将key对应到value并且返回原来key对应的value。如果key存在但是对应的value不是字符串,就返回错误。
redis控制秒杀逻辑
场景
假设10000用户抢10件商品
key 为 kill_goods_id
value 为 时间戳+过期时间(N秒) 1484567899
加锁 (返回bool值)
1、 如果setnx(kill_goods_id, 1484567899) 获得了锁,返回为true,则继续购买,否则等一等
2、 防止死锁,如果锁过期(理论上不会走到这一步,因为下面有解锁的步骤)
get(kill_goods_id) 获取时间oldTime1,如果oldTime1时间不为空或者并且时间小于当前时间newTime(锁过期了;如果oldTime1不存在,说明数据错乱止损),进入下一步
3、 getset(kill_goods_id, newTime) 返回oldTime2,如果 oldTime2不为空并且oldTime2==oldTime1获得锁(如果oldTime2不为空或者!=oldTime1,说明数据错乱,止损)
4、 执行完以上流程剩下的都是需要重新竞争的
执行商品购买逻辑()
a、查询库存是否足够
b、下单
c、减库存
解锁(无返回状态)
加一个解一个
判断get(kill_goods_id)得到oldTime1,如果oldTime1== 1484567899,删除key del(kill_goods_id)
如果此过程有异常,捕获并记录日志