項目開發的時候,開發注冊模塊要生成一個唯一的注冊編號,編號的生成規則為日期+當天注冊數。為了解決並發注冊會引起注冊編號重復的問題就運用的redis的鎖機制來解決這個問題。
<?php
$redis = new Redis(); while ($redis->setnx('lock', time() + 2) == 0) {//加鎖成功並設置超時防止死鎖,setnx當值已經存在則不操作返回0,當值不存在則set值並返回1. if (time() > $redis->get('lock') && time() > $redis->getSet('lock', time() + 2)) {//若加鎖不成功則判斷該鎖是否已經超時,則用getset函數獲取舊值是否真的超時並設置新的超時值。跳出循環執行業務邏輯代碼。 break; } else { //建議用swoole的協程來處理會更加提高性能 sleep(1); }
}
//進行業務邏輯代碼
//釋放redis鎖
$redis->del('lock');
注意:用getset函數而不直接用set函數是防止兩個用戶同時進到循環設置鎖的超時時間,就會發生並發的問題,用getset就保證只有一個用戶加鎖成功。
拿不到鎖的用戶就只能等待,或者直接報錯重新操作也是可以的。
