成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

php 并發(fā)控制中的獨占鎖

yy13818512006 / 1907人閱讀

并發(fā)大家都知道是什么情況,這里說的是并發(fā)多個請求搶占同一個資源,直接上實例吧

請求:index.php?mod=a&action=b&taskid=6
處理:

$key = "a_b::".$uid."_".$taskid;
$v = $redis->get($key);
if($v == 1){
    $redis->setex($key,10,1);
    //處理邏輯省略
}

邏輯看來還可以,結(jié)果發(fā)現(xiàn)數(shù)據(jù)庫中寫入了兩個同樣的請求結(jié)果,我看了記錄的時間戳,天!居然是同一秒.
我用microtime(true) log一下兩個請求的時間差居然相差了0.0001s,就是說$redis->setex($key,10,1);還沒執(zhí)行成功 第二個請求已經(jīng)get到跟第一個請求一樣的結(jié)果。這不就是傳說中的并發(fā)搶占資源。這中情況 聽過很多,在開發(fā)過程中也沒刻意去模擬實驗過
第一反應(yīng)就是要給處理過程加事務(wù)(數(shù)據(jù)庫是mysql innoDB),加事務(wù)的結(jié)果就是 第一個請求成功了 第二個請求會執(zhí)行到后面撿查發(fā)現(xiàn)重了會回滾
其實mysql事務(wù)在保證數(shù)據(jù)一致性上是很ok的,但是通過回滾來保證唯一資源獨占代價太大,做過mysql事務(wù)測試測同學(xué)都知道,事務(wù)中的insert是已經(jīng)插進去了,回滾之后才刪掉的。
還有一個選擇就是php中的文件獨占鎖,那就是說這情況下我要新建 用戶數(shù) * 任務(wù)數(shù)的文件來實現(xiàn)每個請求資源的獨占,如果獨占資源較少的話可選的解決辦法:

    /**
     * 加鎖
     */
    public function file_lock($filename){
        $fp_key = sha1($filename);
        $this->fps[$fp_key] = fopen($filename, "w+");
        if($this->fps[$fp_key]){
            return flock($this->fps[$fp_key], LOCK_EX|LOCK_NB);
        }
        return false;
    }
    /**
     * 解鎖
     */
    public function file_unlock($filename){
        $fp_key = sha1($filename);
        if($this->fps[$fp_key] ){
            flock($this->fps[$fp_key] , LOCK_UN);
            fclose($this->fps[$fp_key] );
        }
    }

發(fā)現(xiàn)$redis->setnx()可以提供原子操作的狀態(tài):相同的key執(zhí)行setnx之后沒過期或者沒del,再執(zhí)行會返回false。這就讓兩個以上的并發(fā)請求得到控制必須成功獲取鎖才能繼續(xù)。
下面的是我實現(xiàn)的代碼:

    /**
     *  加鎖
     */
    public function task_lock($taskid){
            $expire = 2;
             $lock_key ="task_get_reward_".$this->uid."_".$taskid;
            $lock = $this->redis->setNX($lock_key , time());//設(shè)當前時間
            if($lock){
                $this->redis->expire($lock_key,  $expire); //如果沒執(zhí)行完 2s鎖失效
            }
            if(!$lock){//如果獲取鎖失敗 檢查時間
                $time = $this->redis->get($lock_key);
                if(time() - $time  >=  $expire){//添加時間戳判斷為了避免expire執(zhí)行失敗導(dǎo)致死鎖 當然可以用redis自帶的事務(wù)來保證
                    $this->redis->rm($lock_key);
                }
                $lock =  $this->redis->setNX($lock_key , time());
                if($lock){
                    $this->redis->expire($lock_key,  $expire); //如果沒執(zhí)行完 2s鎖失效
                }
            }
            return $lock;
        }
        /**
         *  解鎖
         */
        public function task_unlock($taskid){
            $this->set_redis();
            $lock_key = "task_get_reward_".$this->uid."_".$taskid;
            $this->redis->rm($lock_key);
        }

說明下setNX 和expire 這兩個操作其實可以用redis事務(wù)來保證一致性

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/21934.html

相關(guān)文章

  • php并發(fā)控制中的獨占

    摘要:這中情況聽過很多,在開發(fā)過程中也沒刻意去模擬實驗過。這就讓兩個以上的并發(fā)請求得到控制必須成功獲取鎖才能繼續(xù)。 1.并發(fā)問題并發(fā)大家都知道是什么情況,這里說的是并發(fā)多個請求搶占同一個資源,直接上實例吧 請求:index.php?mod=a&action=b&taskid=6處理: $key = a_b::.$uid._.$taskid; $v = $redis->get($key); i...

    AZmake 評論0 收藏0
  • 【java并發(fā)編程實戰(zhàn)6】AQS之獨占ReentrantLock實現(xiàn)

    摘要:鎖與很好的隔離使用者與實現(xiàn)者所需要關(guān)注的領(lǐng)域。那么這個就是包裝線程并且放入到隊列的過程實現(xiàn)的方法。也證實了就是獲取鎖的線程的節(jié)點。如果發(fā)生異常取消請求,也就是將當前節(jié)點重隊列中移除。 前言 自從JDK1.5后,jdk新增一個并發(fā)工具包java.util.concurrent,提供了一系列的并發(fā)工具類。而今天我們需要學(xué)習(xí)的是java.util.concurrent.lock也就是它下面的...

    sixleaves 評論0 收藏0
  • 深入淺出AQS之共享模式

    摘要:其二如果返回值等于表示當前線程獲取共享鎖成功,但它后續(xù)的線程是無法繼續(xù)獲取的,也就是不需要把它后面等待的節(jié)點喚醒。 在了解了AQS獨占鎖模式以后,接下來再來看看共享鎖的實現(xiàn)原理。 原文地址:http://www.jianshu.com/p/1161... 搞清楚AQS獨占鎖的實現(xiàn)原理之后,再看共享鎖的實現(xiàn)原理就會輕松很多。兩種鎖模式之間很多通用的地方本文只會簡單說明一下,就不在贅述了,...

    Berwin 評論0 收藏0
  • PHP Session并發(fā)操作阻塞問題

    摘要:前段時間的項目中遇到了并發(fā)操作阻塞問題,因為請求會使用存儲數(shù)據(jù)。不過,這只限于來自同一個客戶端的多個請求,也就是說,來自一個客戶端的請求并不會阻塞另一個客戶端的請求。這將大大增加頁面的響應(yīng)時間。至此解決并發(fā)阻塞問題。 ??前段時間的項目中遇到了session并發(fā)操作阻塞問題,因為請求會使用Session存儲數(shù)據(jù)。 ??在同一個客戶端瀏覽器打開不同標簽進行測試的時候,請求一直處于等待狀態(tài)...

    SnaiLiu 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<