incr
比如北京車牌採取先搶到後審批資質的流程。車牌池子中有N多號碼,頁面呈現以一頁十條的方式展示,每個號碼後有一個搶的按鈕,且一個人只能搶一個車牌,同樣一個車牌只能被一個人搶到。業務模型參考
<!– more –>
if ($this->redis_db->incr("bj_".$car_no) != 1) {
讓別人先下手了,點別的去~
}else{
//搶到競態條件,如果不復核資質要求退出,並清除incr
if(搶到了但是沒資質等){
釋放對此id的竟態權,別佔茅坑
$this->yredis_db->del("bj_".$id);
}else{
其他業務A
抱得號碼歸...
其他業務B
}
}
另外,incr
對string
型別,hash
型別,sortedSet
型別都可以進行操作
blpop
blpop
相對於lpop有一個好處,可以對多個佇列進行優先順序操作。blpop
會按照key
的排列順序依次彈出,返回值為key
的listname及具體元素值,而且可以設定block
時間,原則是先阻塞先服務.
$date = date(`Ymd`, time());
//左進左出 ,優先分配一般的車牌號碼,然後在分配非常好的連號號碼,設定一個阻塞時間
return $this->redis->blpop(self::$_config[`dispatch_normal_list`] . $date, self::$_config[`dispatch_better_list`] . $date, self::$_config[`redis_block_l_pop_time_out`]);
hsetnx
設定hash
中一個field
為指定value
,前提是field
不存在。如果存在,返回0。
這樣能保證在一個人只能搶一個車牌,但是搶到車牌執行付款或者其他業務操作過程中,其他人無法對此操作,(即不能將此車牌繫結到其他人身上)。根據具體業務情況,可設定基於car_no的hash field和基於 people 的hash field。
hash_base_people {"zhangsan":"京A888","lisi":"京A999"}
hash_base_car_no {"京A888":"zhangsan","京A999":"lisi"}
基於這兩個hash 可以做更多關於業務的操作,比如通過hget等檢視具體的繫結關係。
hdel
有了通過hsetnx的繫結模型,當某個人對某個車牌交付了訂金等一系列之後,就代表可以永遠的將其消除,這樣會用到hdel。另外如果在指定時間內沒有做比如交付訂金之類的操作,這個車牌號碼會回爐到原始列表中。
//刪除以people_id為key的hash
$base_people_id_del = $this->redis->hdel(self::$_config[`hash_base_people`], $people_id);
//刪除以car_no為key的hash
$base_car_no_del = $this->redis->hdel(self::$_config[`hash_base_car_no`], $clue_id);
lpush
如果有入口將北京可以搶拍的車牌放入到一個list裡
$lpush_res = $redisObj->lpush($list_name, $car_no);
其中list_name的值可以根據car_no的具體值來確定,比如有6和8的我就放入到better_car_no
列表裡,其他的放入到normal_car_no
列表裡,最後可以用blpop
來指定一個先後優先順序。
rpoplpush
安全的佇列彈出模式,比如N多人對一個入口按鈕進行操作,如果list結構中有足夠的資料,每個人有且只有一條資料會被領取,領取之後再做其他的業務操作。
但是問題是,如果用lpop
之後,原佇列中已被彈出,如果中途客戶端在取得該pop
的元素後,且完成處理此元素前,客戶端發生崩潰。這時候此條訊息就憑空消失了。如果沒有其他補助措施(比如通過繫結或者記錄此彈出的元素)需要嚴謹要求,可以用rpoplpus
h可以解決此問題。在客戶端真正處理完此pop
的元素之後,通過lrem
將此訊息安全刪除。