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】

Duplicate
-----------Complicate
--------------------------Appreciate
-----------------------------------------Fate

闻先后,术专攻
三人有师
习得文武艺,货与帝王家
人性不曾变,资本永无眠

-----------花有重开日,人无再少年-----------

  分类目录

  monitor(TD)

往前一步是黄昏,退后一步是人生

渡口边最后一面洒下了句点,与你若只如初见 何须感伤离别

生活远没有咖啡那么苦涩,关键是喝它的人怎么品味!每个人都喜欢和向往随心所欲的生活,殊不知随心所欲根本不是生活。

如果错过了太阳时你流泪了,那么你也要错过群星了。

不如意的时候不要尽往悲伤里钻,想想有笑声的日子吧。

我不明白为什么要那么在意别人的看法,评头论足只是无聊人的消遣,何必看得如临大敌。如果你不吃别人家的饭,就别太把别人的话放在心上。