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]
-----------------------------------------------Elevate

三人行 有吾师

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

  分类目录

  monitor(TD)

在看得见的地方站得直 是因为在看不见的地方站得稳

With great power comes great responsibility :能力越大责任越大。

让你变得更好的那个人,往往是你觉得很难与之相处的那个人

觉得自己做的到和不做的到,其实只在一念之间。

拿破仑波拿巴,他一生打了90%以上的胜仗,你在第一时间想到他一生中最著名的战役是什么?

停止狼狈 让错纯粹。

凡事顺其自然,遇事处于泰然,得意之时淡然,失意之时坦然,艰辛曲折必然,历尽沧桑悟然。