redis的watch使用

ThinkPhp 发表时间:2021-05-05 16:58:34 作者:梁子亮 浏览次数:1155

redis的watch配合事务可以实现乐观锁机制

// 在test1方法中连接redis
$config = config('redis.');
$redis = new \Redis();
$redis->connect($config['redis_host'],$config['redis_port']);
$redis->auth($config['redis_auth']);

//设置key的值为10
$strKey = 'Test_bihu_age';
$re = $redis->set($strKey,10);
$age = $redis->get($strKey);
echo "1---- Current Age:{$age} ---- <br/><br/>"; //10

// 开启事务
$redis->watch($strKey);
$redis->multi();
//在这个时候新开了一个新会话执行
$re1 = $redis->set($strKey,20);  //新会话
print_dump($re1);
echo "2---- Current Age:{$age} ---- <br/><br/>"; //10
$re2 = $redis->set($strKey,30);
// 睡眠5秒,若这5秒期间有其他地方修改了这个"Test_bihu_age"的key(不是上面的set20和set30),则multi至exec期间的redis代码均失效回滚(若有mysql代码是不会回滚的)
sleep(5);
echo "3---- Current Age:{$age} ---- <br/><br/>"; //10
print_dump($re2);
$re3 = $redis->exec();
/* array(2) {
  [0]=>
  bool(true)
  [1]=>
  bool(true)
} */
print_dump($re3);
if($re3){
    print_dump('期间没有修改过key');
    // 进行mysql的操作
    Db::name("ad")->where('id',95)->setField('sort',1);
}else{
    print_dump('期间修改过key需要回滚redis');
    // 无需进行mysql的操作
}
$age = $redis->get($strKey);
echo "4---- Current Age:{$age} ---- <br/><br/>"; //30
die;

在test2方法中,若在test1的sleep 5秒期间修改了Test_bihu_age的值,则test1方法sleep5秒后echo "4---- Current Age:{$age} ---- <br/><br/>"; 的值不再是30,而是test2方法中修改后的值


redis配合watch实现秒杀&抢购功能

$config = config('redis.');
$redis = new \Redis();
$redis->connect($config['redis_host'],$config['redis_port']);
$redis->auth($config['redis_auth']);
$mywatchkey = $redis->get("mywatchkey");
$rob_total = 6;  //抢购数量
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();
    print_dump($rob_result);
    if($rob_result){
        $mywatchlist = $redis->hGetAll("mywatchlist");
        echo "抢购成功!";
        echo "剩余数量:".($rob_total-$mywatchkey-1)."</br>";
        echo "用户列表:";
        var_dump($mywatchlist);
    }else{
        echo "手气不好,再抢购!";exit;
    }
}

上一篇   yac扩展安装&使用