php 基于redis的分布式锁应用

高并发的时候,对关键业务的数据保护,一般是用mysql加锁,有表锁行锁共享排锁一堆。。我选择了redis分布式锁,have a look at the code:

composer require signe/redlock-php

引入这个包之后,代码里面可以这样写:

private function unlock($key)
{
    $servers = [[
        $this->config['cache']['redis']['hosts'],
        $this->config['cache']['redis']['ports'],
        30,
        $this->config['cache']['redis']['auth'],
        $this->config['cache']['redis']['select'],
    ]];
    $redlock = new RedLock($servers);
    return $redlock->unlock($key);
}
private function lock($key, $time = 1000, $retry = 3)
{
    //Cache::getInstance()->delete(md5(3410) . 'showTree');exit;
    $servers = [[
        $this->config['cache']['redis']['hosts'],
        $this->config['cache']['redis']['ports'],
        30,
        $this->config['cache']['redis']['auth'],
        $this->config['cache']['redis']['select'],
    ]];
    $redlock = new RedLock($servers, $retry);
    return $redlock->lock($key, $time);
}

$count = 0;
do {
    if ($lock = $this->lock('recharge_add_lower_level ') . $orders['user_id']) {
        Db::table('t_user')->where('id', $orders['user_id'])->increment('amount', 3000);//$orders['total_amount']
        $this->addLowerLevel($inviter_id, $orders['user_id']);
        $this->unlock($lock);
        break;//正常退出
    }
    if ($count > 5)
        ret(2, '', '锁定金额失败:' . date('Y-m-d H:i:s'));//超时退出
    usleep(200000);
    $count++;
} while (true);

这里遇到一个坑,这个包里默认连接redis是选择db0的,如果需要自由选择db,需要修改这个包的代码:

\vendor\signe\redlock-php\src\RedLock.php
at line:160

if ($db)
     $redis->select($db);

改完之后如下图(增加了161-162两行):

php 基于redis的分布式锁应用_第1张图片


你可能感兴趣的:(PHP)