1. 程式人生 > >php 基於redis的分散式鎖應用

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兩行):