<?php
/**
* 實現Redis分佈鎖
*/
$key = 'test'; //要更新資訊的快取KEY
$lockKey = 'lock:'.$key; //設定鎖KEY
$lockExpire = 10; //設定鎖的有效期為10秒
//獲取快取資訊
$result = $redis->get($key);
//判斷快取中是否有資料
if(empty($result))
{
$status = TRUE;
while ($status)
{
//設定鎖值為當前時間戳 + 有效期
$lockValue = time() + $lockExpire;
/**
* 建立鎖
* 試圖以$lockKey為key建立一個快取,value值為當前時間戳
* 由於setnx()函式只有在不存在當前key的快取時才會建立成功
* 所以,用此函式就可以判斷當前執行的操作是否已經有其他程式在執行了
* @var [type]
*/
$lock = $redis->setnx($lockKey, $lockValue);
/**
* 滿足兩個條件中的一個即可進行操作
* 1、上面一步建立鎖成功;
* 2、 1)判斷鎖的值(時間戳)是否小於當前時間 $redis->get()
* 2)同時給鎖設定新值成功 $redis->getset()
*/
if(!empty($lock) || ($redis->get($lockKey) < time() && $redis->getSet($lockKey, $lockValue) < time() ))
{
//給鎖設定生存時間
$redis->expire($lockKey, $lockExpire);
//******************************
//此處執行插入、更新快取操作...
//******************************
//以上程式走完刪除鎖
//檢測鎖是否過期,過期鎖沒必要刪除
if($redis->ttl($lockKey))
$redis->del($lockKey);
$status = FALSE;
}else{
/**
* 如果存在有效鎖這裡做相應處理
* 等待當前操作完成再執行此次請求
* 直接返回
*/
sleep(2);//等待2秒後再嘗試執行操作
}
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結