樂觀鎖
樂觀鎖大多是基于數據版本記錄機制實現,一般是給數據庫表增加一個"version"字段。讀取數據時,將此版本號一同讀出,之后更新時,對此版本號加一。此時將提交數據的版本數據與數據庫表對應記錄的當前版本信息進行比對,如果提交的數據版本號大于數據庫表當前版本號,則予以更新,否則認為是過期數據。
比如下單操作:
查詢出商品信息。
select (quantity, version)from t_goodswhere id = #{id}
根據商品信息生成訂單。
將商品數量減1。
update t_goodsset quantity = quantity - 1where id = #{id} and version = #{version}
悲觀鎖
悲觀鎖依靠數據庫提供的鎖機制實現。MySQL中的共享鎖和排它鎖都是悲觀鎖。數據庫的增刪改操作默認都會加排他鎖,而查詢不會加任何鎖。
共享鎖(讀鎖)
共享鎖指的就是對于多個不同的事務,對于一個資源共享同一個鎖。對某一資源加共享鎖,自身可可讀該資源,其他人也可以讀該資源(也可以再加共享鎖,即共享鎖共享多個內存),但無法修改。要想修改就必須等所有共享鎖都釋放完之后。語法:select * from table lock in share mode;
。
比如:
窗口1,在一個未結束的事務中給一條數據加上共享鎖。
BEGIN;SELECT * FROM t_red_packet WHERE id = 1 LOCK IN SHARE MODE;
窗口2,給同一條數據加上共享鎖,加鎖成功。
SELECT * FROM t_red_packet WHERE id = 1 LOCK IN SHARE MODE;
窗口1和窗口2,更新該行數據,提示[Err] 1205 - Lock wait timeout exceeded; try restarting transaction
。需要等到所有共享鎖釋放,才可以進行update操作。
UPDATE t_red_packetSET user_id = 2
排它鎖(寫鎖)
排它鎖指的就是對于多個不同的事務,對同一個資源只能有一把鎖。對某一資源加排它鎖,自身可以進行增刪改查,其他人無法進行加鎖操作,更無法進行增刪改操作。語法:select * from table for update
。
窗口1,在一個未結束的事務中給一條數據加上排它鎖。
BEGIN;SELECT * FROM t_red_packet WHERE id = 1 FOR UPDATE;
窗口1,更新該行數據,成功。
UPDATE t_red_packetSET user_id = 2
窗口2,查詢該行數據,可以查詢到。
SELECT * FROM t_red_packet WHERE id = 1
窗口2給該條數據加鎖,提示[Err] 1205 - Lock wait timeout exceeded; try restarting transaction
。
SELECT * FROM t_red_packet WHERE id = 1 FOR UPDATE;
綜上,共享鎖就是大家一起來讀,一起來共享鎖,但誰都不要對鎖著的數據進行修改,排它鎖就是我自己就是想來修改,你們可以讀,但你們都不能到鎖,也不能對數據進行修改。
行鎖
行鎖就是給一行數據進行加鎖。
表鎖
表鎖就是對一張表進行加鎖。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VeVb武林網的支持。
新聞熱點
疑難解答