1. 程式人生 > >mysql的排它鎖、悲觀鎖、樂觀鎖

mysql的排它鎖、悲觀鎖、樂觀鎖

一、先來說說mysql  for update 是mysql的一種加鎖方式,排它鎖,加鎖後別的使用者可以讀取資料,但是不能更改資料。

我們舉一個專案中常見的應用場景吧。 
比如有一張表 他有三個欄位。id代表商品id ,name代表商品名字,count代表該商品數量。 
我們為了顯示搶購的時候顯示該商品還剩餘多少件。我們會手動的上鎖。鎖住id為1的商品。比如id為1的商品名字是某型號的mac pro。count代表了該商品還剩餘多少件。當併發量很大的情況下,商品數量自減的值可能是不準確的。 
所以當我們在一個事務中對count欄位進行修改的時候,其他的事務應該是隻能讀取指定id的count值。而不能寫入或者update。這個時候for update的作用就是在此刻體現的。


比如說sql是這樣的。

start transaction ;
select * from table_name where id =1 for update ;

update table_name set count = count - 1 where id= 1;

此時如果另一個事務也想執行類似的操作。

start transaction ;
select * from table_name where id =1 for update ;
//下面的這行sql會等待,直到上面的事務回滾或者commit才得到執行。
update table_name set count = count - 1 where id= 1;

順帶一提的是,當選中某一個行的時候,如果是通過主鍵id選中的。那麼這個時候是行級鎖。 其他的行還是可以直接insert 或者update的。如果是通過其他的方式選中行,或者選中的條件不明確包含主鍵。這個時候會鎖表。其他的事務對該表的任意一行記錄都無法進行插入或者更新操作。只能讀取。

二、悲觀鎖

悲觀鎖,正如其名,它指的是對資料被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個資料處理過程中,將資料處於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制(也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改資料)。

 使用場景舉例:以MySQL InnoDB為例, 商品goods表中有一個欄位status,status為1代表商品未被下單,status為2代表商品已經被下單,那麼我們對某個商品下單時必須確保該商品status為1。假設商品的id為1。

1如果不採用鎖,那麼操作方法如下:

//1.查詢出商品資訊

select status from t_goods where id=1;

//2.根據商品資訊生成訂單

insert into t_orders (id,goods_id) values (null,1);

//3.修改商品status為2

update t_goods set status=2;

上面這種場景在高併發訪問的情況下很可能會出現問題。

前面已經提到,只有當goods status為1時才能對該商品下單,上面第一步操作中,查詢出來的商品status為1。但是當我們執行第三步Update操作的時候,有可能出現其他人先一步對商品下單把goods status修改為2了,但是我們並不知道資料已經被修改了,這樣就可能造成同一個商品被下單2次,使得資料不一致。所以說這種方式是不安全的。

2使用悲觀鎖來實現:

在上面的場景中,商品資訊從查詢出來到修改,中間有一個處理訂單的過程,使用悲觀鎖的原理就是,當我們在查詢出goods資訊後就把當前的資料鎖定,直到我們修改完畢後再解鎖。那麼在這個過程中,因為goods被鎖定了,就不會出現有第三者來對其進行修改了。

注:要使用悲觀鎖,我們必須關閉mysql資料庫的自動提交屬性,因為MySQL預設使用autocommit模式,也就是說,當你執行一個更新操作後,MySQL會立刻將結果進行提交。

我們可以使用命令設定MySQL為非autocommit模式:

set autocommit=0;

設定完autocommit後,我們就可以執行我們的正常業務了。具體如下:

//0.開始事務

begin;/begin work;/start transaction; (三者選一就可以)

//1.查詢出商品資訊

select status from t_goods where id=1 for update;

//2.根據商品資訊生成訂單

insert into t_orders (id,goods_id) values (null,1);

//3.修改商品status為2

update t_goods set status=2;

//4.提交事務

commit;/commit work;

注:上面的begin/commit為事務的開始和結束,因為在前一步我們關閉了mysql的autocommit,所以需要手動控制事務的提交,在這裡就不細表了。

上面的第一步我們執行了一次查詢操作:select status from t_goods where id=1 for update;

與普通查詢不一樣的是,我們使用了select…for update的方式,這樣就通過資料庫實現了悲觀鎖。此時在t_goods表中,id為1的 那條資料就被我們鎖定了,其它的事務必須等本次事務提交之後才能執行。這樣我們可以保證當前的資料不會被其它事務修改。

三、樂觀鎖(所有使用者都可以讀取和修改,通過版本控制誰的修改有效)

相關推薦

mysql 之行間隙後碼

MySQL InnoDB支援三種行鎖定 行鎖(Record Lock):鎖直接加在索引記錄上面,鎖住的是key。 間隙鎖(Gap Lock):鎖定索引記錄間隙,確保索引記錄的間隙不變。間隙鎖是針對事務隔離級別為可重複讀或以上級別而設計的。 後碼鎖(Next-Key Lock):行鎖和間隙鎖組合起來就叫Nex

深入Mysql機制(四)樂觀悲觀

深入Mysql鎖機制(四)樂觀鎖與悲觀鎖 在資料庫鎖機制中介紹過,資料庫管理系統(DBMS)中的併發控制的任務是確保在多個事務同時存取資料庫中同一資料時不破壞事務的隔離性和統一性以及資料庫的統一性。 樂觀併發控制(樂觀鎖)和悲觀併發控制(悲觀鎖)是併發控制主要採用的技術手段。

mysql數據庫怎麽設置樂觀

reat 比較 sql語句 blog 悲觀鎖 class product 數量 pre 樂觀鎖與悲觀鎖不同的是,它是一種邏輯上的鎖,而不需要數據庫提供鎖機制來支持當數據很重要,回滾或重試一次需要很大的開銷時,需要保證操作的ACID性質,此時應該采用悲觀鎖而當數據對即時的一致

深入Mysql機制(五)樂觀CAS

深入Mysql鎖機制(五)樂觀鎖CAS 執行緒安全 眾所周知,Java是多執行緒的。但是,Java對多執行緒的支援其實是一把雙刃劍。一旦涉及到多個執行緒操作共享資源的情況時,處理不好就可能產生執行緒安全問題。執行緒安全性可能是非常複雜的,在沒有充足的同步的情況下,多個執行緒中的操

mysql 悲觀共享

悲觀鎖 與樂觀鎖相對應的就是悲觀鎖了。悲觀鎖就是在操作資料時,認為此操作會出現資料衝突,所以在進行每次操作時都要通過獲取鎖才能進行對相同資料的操作,這點跟java中的synchronized很相似,所以悲觀鎖需要耗費較多的時間。另外與樂觀鎖相對應的,悲觀鎖是由資料庫自己實現了的,要用的時候,我們

mysql樂觀悲觀共享

我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突) 樂觀鎖 樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在操作資料時,並不進行任何其他的特殊處理(也就是不加鎖),而在進行更新後,再去判斷是否

mysql樂觀悲觀共享概念的理解

實驗環境: mysql5.6 儲存引擎:innoDB 我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突) 樂觀鎖 樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在

MySQL樂觀悲觀共享的概念

樂觀鎖 樂觀鎖是指在操作資料庫時(更新操作),想法很樂觀,認為此次操作不會導致衝突,所以在操作資料時,不進行任何其他的特殊處理(也就是不加鎖),而在進行更新後,再去判斷是否有衝突。 悲觀鎖 悲觀鎖是指在操作資料庫時(更新操作),想法很悲觀,認為此次操作會出現衝突,所以在

MySQL/InnoDB中,樂觀悲觀共享概念的理解

MySQL/InnoDB的加鎖,一直是一個面試中常問的話題。例如,資料庫如果有高併發請求,如何保證資料完整性?產生死鎖問題如何排查並解決?我在工作過程中,也會經常用到,樂觀鎖,排它鎖,等。於是今天就對這幾個概念進行學習,屢屢思路,記錄一下。 注:MySQL是一

MySQL/InnoDB中的悲觀共享MySQL讀寫分離

MySQL/InnoDB的加鎖,一直是一個面試中常問的話題。例如,資料庫如果有高併發請求,如何保證資料完整性?產生死鎖問題如何排查並解決?我在工作過程中,也會經常用到,樂觀鎖,排它鎖,等。於是今天就對這幾個概念進行學習,屢屢思路,記錄一下。 注:MySQL是一個支援

mysql悲觀樂觀

一、先來說說mysql  for update 是mysql的一種加鎖方式,排它鎖,加鎖後別的使用者可以讀取資料,但是不能更改資料。 我們舉一個專案中常見的應用場景吧。  比如有一張表 他有三個欄位。id代表商品id ,name代表商品名字,count代表該商品數量。 我們

MySQL中的樂觀悲觀共享概念

下文的所有介紹,都是基於InnoDB儲存引擎,其他引擎的表現,會有較大的區別。 樂觀鎖 用資料版本(Version)記錄機制實現,是樂觀鎖最常用的一種實現方式。什麼是資料版本?即為資料增加一個版本標識,一般是通過為資料庫表增加一個數字型別的“version”欄位來實現

mysql樂觀悲觀共享概念的理解 (轉)

而在 狀態 line 主鍵 n) efault 你家 不一致 開啟 實驗環境: mysql5.6 存儲引擎:innoDB 我們在操作數據庫的時候,可能會由於並發問題而引起的數據的不一致性(數據沖突) 樂觀鎖樂觀鎖不是數據庫自帶的,需要我們自己去實現。樂觀鎖是指操作數據庫

【轉】【MySQLMySQL中的(表,共享,間隙

https://blog.csdn.net/soonfly/article/details/70238902 本文參考:  http://mysqlpub.com/thread-5383-1-1.html  http://blog.csdn.net/c466254931/ar

樂觀悲觀共享以及的概念

樂觀鎖 樂觀併發控制(又名”樂觀鎖”,Optimistic Concurrency Control,縮寫”OCC”),它假設多使用者併發的事務在處理時不會彼此互相影響,各事務能夠在不產生鎖的情況下處理各自影響的那部分資料。在提交資料更新之前,每個事務會先檢查在該事務讀取資料後,有沒有其他事務

資料庫中樂觀悲觀共享的理解

mysql5.6 我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突) 樂觀鎖 樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在操作資料時,並不進行任何其他的特殊處理(也就

資料庫樂觀悲觀共享概念的理解

實驗環境:mysql5.6儲存引擎:innoDB我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突)樂觀鎖樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在操作資料時,並不進行任何

對於Zookeeper中提及的共享悲觀樂觀的理解

排它鎖 (簡稱X鎖),又稱為寫鎖或獨佔鎖,是一種基本的鎖型別。如果事務T1對資料物件O1加上了排它鎖,那麼在整個加鎖期間,只允許事務T1對O1進行讀取和更新操作,其它任何事務都幫你再對這個資料物件進行任何型別的操作,——直到T1釋放了排它鎖。 從上邊講解的排

MySQL-----(行樂觀悲觀

數據庫操作 重要 讀寫 收購 線程並發 串行化 之前 並發執行 引擎 回顧: ACID:DBMS在寫入或更新資料的過程中,為保證事務正確可靠,具有的四個特性:原子性(不可分割性)、一致性、隔離性(獨立性)、持久性 一個事務:一系列數據庫操作組成的一個完整的邏輯過程 原子性:

最簡單理解Mysql共享排他樂觀悲觀

共享鎖 select * from xx where id = 10 lock in share mode 排他鎖 select * from xx where id = 10 for update 樂觀鎖 select num,version from xx where id = 10