class Lock { const PREFIX_KEY = "MY_LOCK:"; static private $LOCKED = []; static public function tryLock($key, $expire = 300) { $lock = self::PREFIX_KEY.$key; //已取獲得lock(防止同行程重覆要求形成deadlock) if(self::$LOCKED[$lock]) { ++self::$LOCKED[$lock]; return true; } //處理lock $redis = &AppBase::getRedis(); if(!$redis->setnx($lock, '')) { return false; } $redis->expire($lock, $expire); //防止crash沒解鎖 //成功lock ++self::$LOCKED[$lock]; return true; } static public function unlock($key) { $lock = self::PREFIX_KEY.$key; if(--self::$LOCKED[$lock] <= 0) { AppBase::getRedis()->delete($lock); unset(self::$LOCKED[$lock]); } } static public function blockLock($key, $max_try = 60, $sleep = 1, $expire = 300) { $t = 0; while(++$t <= $max_try) { if(self::tryLock($key, $expire)) { return true; } usleep(intval($sleep * 1000000)); } return false; } }