一、簡介
樂觀鎖是自己通過加字段如version實現的,而非數據庫自帶的。適用於鎖衝突比較小的情況。
悲觀鎖是通過for update添加的,數據庫的鎖,適用於鎖衝突比較大的情況;
二、樂觀鎖
2.1 思路
- 先給表添加一個整型的version字段;
- 先查詢出來當前記錄的version, 然後修改當前記錄相關信息,並且將version的值改爲version + 1, 條件除了相關的,還需要加上version = 上面查詢出來的version的值; 通過version條件即可判斷這段時間是否有併發修改操作,如果有的話,version值已經被加一過的,是不相等的,這樣就不會再次修改了,如果沒有的話,就可以直接修改,從而保證了併發;
2.2 代碼案例 TODO
- 查詢出商品信息 select (status,status,version) from t_goods where id=#{id}
- 根據商品信息生成訂單
- 修改商品status爲2 update t_goods set status=2,version=version+1 where id=#{id} and version=#{version};
2.3 思考
三、悲觀鎖
3.1 思路
- 悲觀鎖是通過for update添加的,數據庫的鎖,適用於鎖衝突比較大的情況;
- 悲觀鎖涉及到倆個數據庫鎖,一個是共享鎖,一個是排它鎖‘
- 共享鎖又稱讀鎖,簡稱S鎖,多個事務對於同一個數據可以共享一把鎖,都能讀數據,但是不能改數據;
- select ... lock in share mode
- 排它鎖又稱寫鎖,簡稱X鎖,排它鎖不能和其它鎖共存,如一個事務獲取了一個數據行的排它鎖,其他事務就不能再對該行數據繼續疊加其它鎖,包括共享鎖和排它鎖。但是擁有該排它鎖的事務是可以對數據行進行讀取和修改的;
- select ...for update
- mysql InnoDB引擎默認的修改數據語句,update,delete,insert都會自動給涉及到的數據加上排他鎖;
- select語句默認不會加任何鎖類型。所以加了排它鎖的記錄使用單純的select是仍然可以查詢到記錄的,但是使用了讀寫鎖的查詢是需要等待排它鎖釋放之後纔可以查詢到記錄的。
- 悲觀鎖在使用的時候必須手動關閉事務自動提交;
3.2 模擬案例 TODO
https://www.jianshu.com/p/e5d193cf4b40