php+mysql使用樂觀鎖和悲觀鎖解決並發減庫存問題

publish:May 13, 2016 -Friday by 04007 本站原創文章,轉載請註明文章出處:www.04007.cn
樂觀鎖和悲觀鎖看名稱挺高大上的,面試的時候一些面試官最喜歡拿這個來考應聘者。這個也是有意義的,一個PHP程序員如果沒有接觸過樂觀鎖和非觀鎖,那麼他根本沒有接觸過像樣的業務了。

什麼是悲觀鎖?看意思就是比較,不相信其它的人不會改,所以查詢的時候就加鎖,然後自己更新數據再釋放鎖。可以有效防止減庫存衝突問題。

什麼是樂觀鎖?相反就是認為沒幾個人用,基本不會碰到有人修改,所以查詢時就不加鎖,然後更新的時候判斷一下數據是不是被改掉。

在php+mysql程序中怎麼實現呢?代碼也很簡單。

悲觀鎖的業務流程(以商品表和SKU表減庫存並進行其它操作為類):

—事務開始

1,查詢商品表、鎖定表:for update

2,判斷商品庫存是否大於購買數據,

3,如果庫存滿足,減少商品表庫存。 (不滿足就回滾事務了。)

4,減少商品SKU表庫存

5,記錄訂單操作記錄等

–事務提交(事務提交時即釋放鎖)。

可見上面的流程中整個被鎖的周期是比較長的。如果改為樂觀鎖呢:

—-事務開始

1,查詢商品表

2,判斷商品庫存是否大於購買數據,

3,如果庫存滿足,減少商品表庫存(條件是商品表的庫存=1中查詢出的庫存)

比如:update product set store = store – {$count} where store = {$product->store} ($product->store為1查詢得到的庫存)

4,減少商品SKU表庫存(同樣需要判斷條件)

5,記錄訂單操作記錄等

–事務提交(事務提交時即釋放鎖)。

可以看到樂觀鎖整個過程中實際並未執行任何加鎖,我也不知道為什麼會有這樣的稱呼。實際它是一種判斷衝突的有效手段。

在上面的樂觀鎖的執行流程中,如果3、4、5這三步中的任何一步發生異常,都會因滾事務。這樣就不會出現減庫存衝突導致庫存臟數據了。

————————————————– ———–

在使用樂觀鎖時,要考慮進一步,就是在樂觀鎖時如果發現數據被修改,更新失敗時,要考慮再重新獲取數據,重新判斷重新更新。這樣就不會因為更新失敗導致此筆業務失敗,而相當於把它立即加進到下一步的隊列而在同步請求中即能得到解決。

兩種鎖各有各的好,建議電商網站起步時訪問量不大,不會造成壓力時使用悲觀鎖。因為這時沒有什麼高並發,但也要好好檢查代碼防止出現死鎖。

對於成熟的電商網站,必鬚麵對高並發的情況下,應該使用樂觀鎖。

本文地址:http://www.04007.cn/article/112.html 未經許可,不得轉載.

Views: 27