redis是沒有鎖定機制的喲,對於多個使用者連線也不存在競爭問題。
但是在進行並發時可能會出現連線逾時,連線被阻塞或是連線被關閉之類的錯誤。 (建議學習:Redis影片教學)
一般可以透過在客戶端將連線做池化處理(例如使用synchronized,在讀寫redis時加內部鎖定),或是在伺服器端用redis自帶的事務處理指令setnx,來實現鎖定。
在電商活動中,經常會有「秒殺」的搶購活動,這種場景,伺服器通常面臨高並發的請求處理。
也就是說,在同一時間,會有大量並發的用戶同時去購買某個商品,這時候,就需要保證不會出現過度出售的情況(用戶最終購買的商品數量超過實際的商品數量)。
這裡就需要應用到redis中加鎖和解鎖的特性來保證每次的購物操作只有一個用戶在進行,避免出現競爭導致髒數據的情況發生。
下面,我們來介紹如何正確使用加鎖和解鎖。
setnx
redis官方在鎖定操作上是建議使用set指令來進行,使用方式如下:
if ($redis->set('my:lock', 1, ['NX'])) { # todo $redis->del('my:lock'); }
其中
NX — 表示只有key不存在的時候才設定
這個方法有個問題,假如一個客戶端獲取到鎖後發生奔潰或一直佔用著鎖不釋放,就會導致死鎖,使得後續的使用者無法取得到鎖進行操作。所以這個操作需要設定一個超時時間。
setnx的改進
針對上面方法的問題,我們使用expire方法設定逾時時間。但到這裡就解決問題了嗎?
沒有!因為這裡expire不是原子操作,如果在操作完setnx後客戶端奔潰,這時候就沒有成功設定超時時間,同樣使得加鎖操作面臨上面的問題。
if ($redis->set('my:lock', 1, ['NX'])) { $redis->expire('my:lock', 10); # todo $redis->del('my:lock'); }
更多Redis相關技術文章,請造訪Redis資料庫使用入門教學欄位學習!
以上是redis保存資料的時候會加鎖嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!