redis watch 乐观锁实现秒杀 /防止超卖

在 Redis 中使用 watch 命令可以决定事务是执行还是回滚。一般而言,可以在 multi 命令之前使用 watch 命令监控某些键值对,然后使用 multi 命令开启事务,执行各类对数据结构进行操作的命令,这个时候这些命令就会进入队列。

当 Redis 使用 exec 命令执行事务的时候,它首先会去比对被 watch 命令所监控的键值对,如果没有发生变化,那么它会执行事务队列中的命令,提交事务;如果发生变化,那么它不会执行任何事务中的命令,而去事务回滚。无论事务是否回滚,Redis 都会去取消执行事务前的 watch 命令。

function testwatch(){
    $redis = redis();
    $mywatchkey = $redis->get("mywatchkey");
    $rob_total = 100;   //抢购数量
    if($mywatchkey<$rob_total){
        $redis->watch("mywatchkey");
        $redis->multi();

        //设置延迟,方便测试效果。
        sleep(2);

        //插入抢购数据
        $redis->hSet("mywatchlist","user_id_".mt_rand(1, 9999),time());
        $redis->set("mywatchkey",$mywatchkey+1);

        $rob_result = $redis->exec();
        if($rob_result){
            $mywatchlist = $redis->hGetAll("mywatchlist");
            echo "抢购成功!<br/>";
            echo "剩余数量:".($rob_total-$mywatchkey-1)."<br/>";
            echo "用户列表:<pre>";
            var_dump($mywatchlist);
        }else{
            echo "手气不好,再抢购!";exit;
        }
    }
}


不知为何 在上述php测试中一直无法成功实现watch回滚功能

但是在cli中 操作watch可以

估计应是连接问题?

/*

     * By default each template method call creates a new connection - so
     * WATCH, MUTLI, EXEC, UNWATCH won't work because of the missing
     * context. To make use of transaction support use SessionCallback which
     * reuses the underlying connection.
     */

missing context?
终端1

127.0.0.1:6379> get fffffaa
"1280"
127.0.0.1:6379> watch fffffaa
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set fffffaa 9999
QUEUED
127.0.0.1:6379> exec
(nil)

终端2

中间时点set即可测试

您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。
本站大部分内容收集于互联网,如果有侵权内容、不妥之处,请联系删除。敬请谅解!

  关于博主【WANG-FEiHU】

Replicate
-----------Complicate
--------------------------Appreciate
----------------------------------------[Fate]
-----------------------------------------------Elevate

三人行 有吾师

-------------花有重开日 梦无止境时-------------

  分类目录

  monitor(TD)

青春就是用来追忆的,当你怀揣着它时,它一文不值,只有将它耗尽后,再回过头看,一切才有了意义,爱过我们的人和伤害过我们的人,都是我们青春存在的意义。

在这有限的时间里,我们应该珍惜生命,珍惜机会,更要珍惜那得之不易的时间。因那滴答做响的时间脚步,一旦走过,再不回头。

要打败任何事情得先学会打败自己。

我会把每一次改变当做成长,哪怕是痛也值得。

时无英雄,使竖子成名

少年不识愁滋味,爱上层楼。爱上层楼。为赋新词强说愁。而今识尽愁滋味,欲说还休。欲说还休。却道天凉好个秋。