php 基於redis的分散式鎖應用
阿新 • • 發佈:2019-01-22
高併發的時候,對關鍵業務的資料保護,一般是用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兩行):