併發大家都知道是什麼情況,這裡說的是併發多個請求搶占同乙個資源,直接上例項吧
請求:index.php?mod=a&action=b&taskid=6
處理:
$key = "a_b::".$uid.'_'.$taskid;
$v = $redis->get($key);
if($v == 1)
邏輯看來還可以,結果發現資料庫中寫入了兩個同樣的請求結果,我看了記錄的時間戳,天!居然是同一秒.
我用microtime(true) log一下兩個請求的時間差居然相差了0.0001s,就是說$redis->setex($key,10,1);還沒執行成功 第二個請求已經get到跟第乙個請求一樣的結果。這不就是傳說中的併發搶占資源。這中情況 聽過很多,在開發過程中也沒刻意去模擬實驗過
第一反應就是要給處理過程加事務(資料庫是mysql innodb),加事務的結果就是 第乙個請求成功了 第二個請求會執行到後面撿查發現重了會回滾
其實mysql事務在保證資料一致性上是很ok的,但是通過回滾來保證唯一資源獨佔代價太大,做過mysql事務測試測同學都知道,事務中的insert是已經插進去了,回滾之後才刪掉的。
還有乙個選擇就是php中的檔案獨佔鎖,那就是說這情況下我要新建 使用者數 * 任務數的檔案來實現每個請求資源的獨佔,如果獨佔資源較少的話可選的解決辦法:
/**
* 加鎖
*/public function file_lock($filename)
return false;
}/**
* 解鎖
*/public function file_unlock($filename)
}
發現$redis->setnx()可以提供原子操作的狀態:相同的key執行setnx之後沒過期或者沒del,再執行會返回false。這就讓兩個以上的併發請求得到控制必須成功獲取鎖才能繼續。
下面的是我實現的**:
/**
* 加鎖
*/public function task_lock($taskid)
if(!$lock)
$lock = $this->redis->setnx($lock_key , time());
if($lock)
}return $lock;
}/**
* 解鎖
*/public function task_unlock($taskid)
說明下setnx 和expire 這兩個操作其實可以用redis事務來保證一致性 php學習之併發控制中的獨佔鎖
在php開發 1.併發問題 併發大家都知道是什麼情況,這裡說的是併發多個請求搶占同乙個資源,直接上例項吧 請求 index.php?mod a action b taskid 6 處理 key a b uid.taskid v redis get key if v 1 redis setex key...
mysql 獨佔鎖 mysql的獨佔鎖和共享鎖
當有多個事務同時更新一條sql時,mysql是如何處理的呢?很顯然,使用加鎖的方式,乙個事務獲得了鎖,進行操作,其他事務排隊乙個個等著,等當前這個事務執行完釋放鎖,其他事務獲取鎖取到鎖的進行操作。這裡的鎖就是獨佔鎖,也就是x鎖。那麼如果有查詢這一行資料時,是要加鎖嗎?不是的,mysql為了提高效能,...
併發控制中的樂觀鎖與悲觀鎖
在多使用者環境中,在同一時間可能會有多個使用者更新相同的記錄,這會產生衝突。這就是著名的併發性問題。1 丟失更新 乙個事務的更新覆蓋了其它事務的更新結果,就是所謂的更新丟失。例如 使用者a把值從6改為2,使用者b把值從2改為6,則使用者a丟失了他的更新。2 髒讀 當乙個事務讀取其它完成一半事務的記錄...