MySQL中的樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖、死鎖概念
下文的所有介紹,都是基於InnoDB儲存引擎,其他引擎的表現,會有較大的區別。
樂觀鎖
用資料版本(Version)記錄機制實現,是樂觀鎖最常用的一種實現方式。什麼是資料版本?即為資料增加一個版本標識,一般是通過為資料庫表增加一個數字型別的“version”欄位來實現。當讀取資料時,將version欄位的值一同讀出,資料每更新一次,對此version值加1。當我們提交更新的時候,判斷資料庫表對應記錄的當前版本資訊與第一次取出來的version值進行比對,如果資料庫表當前版本號與第一次取出來的version值相等,則予以更新,否則認為是過期資料。
舉例
1、資料庫表設計
三個欄位,分別是id、value、version
select id,value,version from TABLE where id=#{id}
2.每次更新表中的value欄位時,為了防止發生衝突,需要這樣操作
- update TABLE
- set value=2,version=version+1 where id=#{id} and version=#{version};
悲觀鎖
與樂觀鎖相對應的就是悲觀鎖。悲觀鎖就是在操作資料時,認為此操作會出現資料衝突,所以在進行每次操作時都要通過獲取鎖才能進行對相同資料的操作,所以悲觀鎖要耗費較多的時間。另外與樂觀鎖相對應的,悲觀鎖是由資料庫自己實現的,要用的時候,直接呼叫資料庫的相關語句就可以了。
至此,由悲觀鎖涉及到的另外兩個鎖概念就出來了,它們就是共享鎖與排它鎖。共享鎖和排它鎖是悲觀鎖的不同實現,他倆都屬於悲觀鎖的範疇。
使用排它鎖舉例
要使用悲觀鎖,我門必須關閉mysql資料庫的自動提交屬性,因為MySQL預設使用autocommit模式,也就是說,當你執行一個更新操作後,MYSQL會立刻將結果進行提交。
我們可以使用命令設定MySQL為非autocommit模式:
- set autocommit=0;
- # 設定完autocommit之後,我門就可以執行我們的正常業務了。具體如下:
- # 1. 開始事務
- begin;/begin work;/start transaction;(三者選一就可以)
- # 2. 查詢表資訊
- select status from TABLE where id=1 for update;
- # 3. 插入一條資料
- insert into TABLE (id,value) values (2,2);
- # 4. 修改資料為
- update TABLE set value=2 where id=1;
- # 5. 提交事務
- commit;/commit work;
共享鎖
共享鎖又稱讀鎖 read lock,是讀取操作建立的鎖。其他使用者可以併發讀取資料,但任何事務都不能對資料進行修改(獲取資料上的排它鎖),直到已釋放所有共享鎖。
如果事務T對資料A加上共享鎖後,則其他事務只能對A再加共享鎖,不能加排它鎖。獲得共享鎖的事務只能讀資料,不能修改資料
開啟第一個查詢視窗
- begin;/begin work;/start transaction;
- SELECT * from TABLE where id=1 lock in share mode;
然後在另一個查詢視窗中,對id為1的資料進行更新
update TABLE set name="www.huaying.com"where id =1;
此時,操作介面進入了卡頓狀態,過了超時間,提示錯誤資訊
如果在超時前,執行 commit
,此更新語句就會成功。
- [SQL]update test_one set name="www.huaying.com" where id =1;
- [Err] 1205 - Lock wait timeout exceeded; try restarting transaction
加上共享鎖後,也提示錯誤資訊
update test_one set name="www.huaying.com" where id =1 lock in share mode;
- [SQL]update test_one set name="www.huaying.com" where id =1 lock in share mode;
- [Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'lock in share mode' at line 1
在查詢語句後面增加 LOCK IN SHARE MODE
,Mysql會對查詢結果中的每行都加共享鎖,當沒有其他執行緒對查詢結果集中的任何一行使用排他鎖時,可以成功申請共享鎖,否則會被阻塞。其他執行緒也可以讀取使用了共享鎖的表,而且這些執行緒讀取的是同一個版本的資料。
加上共享鎖後,對於update,insert,delete
語句會自動加排它鎖。
排它鎖
排他鎖 exclusive lock(也叫writer lock)又稱寫鎖。
排它鎖是悲觀鎖的一種實現,在上面悲觀鎖也介紹過。
若事務 1 對資料物件A加上X鎖,事務 1 可以讀A也可以修改A,其他事務不能再對A加任何鎖,直到事物 1 釋放A上的鎖。這保證了其他事務在事物 1 釋放A上的鎖之前不能再讀取和修改A。排它鎖會阻塞所有的排它鎖和共享鎖
讀取為什麼要加讀鎖呢:防止資料在被讀取的時候被別的執行緒加上寫鎖,
使用方式:在需要執行的語句後面加上for update
就可以了
行鎖
行鎖又分共享鎖和排他鎖,由字面意思理解,就是給某一行加上鎖,也就是一條記錄加上鎖。
注意:行級鎖都是基於索引的,如果一條SQL語句用不到索引是不會使用行級鎖的,會使用表級鎖。
共享鎖:
名詞解釋:共享鎖又叫做讀鎖,所有的事務只能對其進行讀操作不能寫操作,加上共享鎖後在事務結束之前其他事務只能再加共享鎖,除此之外其他任何型別的鎖都不能再加了。
SELECT * from TABLE where id = "1" lock in share mode; 結果集的資料都會加共享鎖
排他鎖:
名詞解釋:若某個事物對某一行加上了排他鎖,只能這個事務對其進行讀寫,在此事務結束之前,其他事務不能對其進行加任何鎖,其他程序可以讀取,不能進行寫操作,需等待其釋放。
select status from TABLE where id=1 for update;
可以參考之前演示的共享鎖,排它鎖語句
由於對於表中,id欄位為主鍵,就也相當於索引。執行加鎖時,會將id這個索引為1的記錄加上鎖,那麼這個鎖就是行鎖。
表鎖
如何加表鎖
innodb 的行鎖是在有索引的情況下,沒有索引的表是鎖定全表的.
Innodb中的行鎖與表鎖
前面提到過,在Innodb引擎中既支援行鎖也支援表鎖,那麼什麼時候會鎖住整張表,什麼時候或只鎖住一行呢?
只有通過索引條件檢索資料,InnoDB才使用行級鎖,否則,InnoDB將使用表鎖!
在實際應用中,要特別注意InnoDB行鎖的這一特性,不然的話,可能導致大量的鎖衝突,從而影響併發效能。
行級鎖都是基於索引的,如果一條SQL語句用不到索引是不會使用行級鎖的,會使用表級鎖。行級鎖的缺點是:由於需要請求大量的鎖資源,所以速度慢,記憶體消耗大。
死鎖
死鎖(Deadlock)
所謂死鎖:是指兩個或兩個以上的程序在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。由於資源佔用是互斥的,當某個程序提出申請資源後,使得有關程序在無外力協助下,永遠分配不到必需的資源而無法繼續執行,這就產生了一種特殊現象死鎖。
解除正在死鎖的狀態有兩種方法:
第一種:
1.查詢是否鎖表
show OPEN TABLES where In_use > 0;
2.查詢程序(如果您有SUPER許可權,您可以看到所有執行緒。否則,您只能看到您自己的執行緒)
show processlist
3.殺死程序id(就是上面命令的id列)
kill id
第二種:
1:檢視當前的事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
2:檢視當前鎖定的事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
3:檢視當前等鎖的事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
殺死程序
kill 程序ID
如果系統資源充足,程序的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則就會因爭奪有限的資源而陷入死鎖。其次,程序執行推進順序與速度不同,也可能產生死鎖。
產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個程序使用。
(2) 請求與保持條件:一個程序因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:程序已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 迴圈等待條件:若干程序之間形成一種頭尾相接的迴圈等待資源關係。
雖然不能完全避免死鎖,但可以使死鎖的數量減至最少。將死鎖減至最少可以增加事務的吞吐量並減少系統開銷,因為只有很少的事務回滾,而回滾會取消事務執行的所有工作。由於死鎖時回滾而由應用程式重新提交。
下列方法有助於最大限度地降低死鎖:
(1)按同一順序訪問物件。
(2)避免事務中的使用者互動。
(3)保持事務簡短並在一個批處理中。
(4)使用低隔離級別。
(5)使用繫結連線。
相關推薦
MySQL中樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖的概念
樂觀鎖 樂觀鎖是指在操作資料庫時(更新操作),想法很樂觀,認為此次操作不會導致衝突,所以在操作資料時,不進行任何其他的特殊處理(也就是不加鎖),而在進行更新後,再去判斷是否有衝突。 悲觀鎖 悲觀鎖是指在操作資料庫時(更新操作),想法很悲觀,認為此次操作會出現衝突,所以在
mysql操作表時出現死鎖解決方式
情景:有時頻繁地某個表時,發現不能進行增刪改操作時,出現操作超時死鎖的情況 --顯示所有程序 show processlist kill id --顯示是否有死鎖 show open tables where In_use > 0; --檢視死鎖 se
MySQL中鎖詳解(行鎖、表鎖、頁鎖、悲觀鎖、樂觀鎖等)
原文地址:http://blog.csdn.net/mysteryhaohao/article/details/51669741 鎖,在現實生活中是為我們想要隱藏於外界所使用的一種工具。在計算機中,是協調多個程序或執行緒併發訪問某一資源的一種機制。在資料庫當中,除了傳統
MySQL/InnoDB中,樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖、死鎖概念的理解
MySQL/InnoDB的加鎖,一直是一個面試中常問的話題。例如,資料庫如果有高併發請求,如何保證資料完整性?產生死鎖問題如何排查並解決?我在工作過程中,也會經常用到,樂觀鎖,排它鎖,等。於是今天就對這幾個概念進行學習,屢屢思路,記錄一下。 注:MySQL是一
MySQL中的樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖、死鎖概念
下文的所有介紹,都是基於InnoDB儲存引擎,其他引擎的表現,會有較大的區別。 樂觀鎖 用資料版本(Version)記錄機制實現,是樂觀鎖最常用的一種實現方式。什麼是資料版本?即為資料增加一個版本標識,一般是通過為資料庫表增加一個數字型別的“version”欄位來實現
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
mysql樂觀鎖、悲觀鎖、共享鎖、排它鎖
我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突) 樂觀鎖 樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在操作資料時,並不進行任何其他的特殊處理(也就是不加鎖),而在進行更新後,再去判斷是否
對mysql樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖概念的理解
實驗環境: mysql5.6 儲存引擎:innoDB 我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突) 樂觀鎖 樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在
資料庫中樂觀鎖、悲觀鎖、共享鎖和排它鎖的理解
mysql5.6 我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突) 樂觀鎖 樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在操作資料時,並不進行任何其他的特殊處理(也就
MySQL/InnoDB中的鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖、死鎖與MySQL讀寫分離
MySQL/InnoDB的加鎖,一直是一個面試中常問的話題。例如,資料庫如果有高併發請求,如何保證資料完整性?產生死鎖問題如何排查並解決?我在工作過程中,也會經常用到,樂觀鎖,排它鎖,等。於是今天就對這幾個概念進行學習,屢屢思路,記錄一下。 注:MySQL是一個支援
Mysql共享鎖、排他鎖、悲觀鎖、樂觀鎖及其使用場景
一、相關名詞 |--表級鎖(鎖定整個表) |--頁級鎖(鎖定一頁) |--行級鎖(鎖定一行) |--共享鎖(S鎖,MyISAM 叫做讀鎖) |--排他鎖(X鎖,MyISAM 叫做寫鎖) |--悲觀鎖(抽象性,不真實存在這個鎖) |--樂觀鎖(抽象性,不真實存在這個鎖) 二
對於Zookeeper中提及的排它鎖、共享鎖和悲觀鎖、樂觀鎖的理解
排它鎖 (簡稱X鎖),又稱為寫鎖或獨佔鎖,是一種基本的鎖型別。如果事務T1對資料物件O1加上了排它鎖,那麼在整個加鎖期間,只允許事務T1對O1進行讀取和更新操作,其它任何事務都幫你再對這個資料物件進行任何型別的操作,——直到T1釋放了排它鎖。 從上邊講解的排
mysql的排它鎖、悲觀鎖、樂觀鎖
一、先來說說mysql for update 是mysql的一種加鎖方式,排它鎖,加鎖後別的使用者可以讀取資料,但是不能更改資料。 我們舉一個專案中常見的應用場景吧。 比如有一張表 他有三個欄位。id代表商品id ,name代表商品名字,count代表該商品數量。 我們
對mysql樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖概念的理解 (轉)
而在 狀態 line 主鍵 n) efault 你家 不一致 開啟 實驗環境: mysql5.6 存儲引擎:innoDB 我們在操作數據庫的時候,可能會由於並發問題而引起的數據的不一致性(數據沖突) 樂觀鎖樂觀鎖不是數據庫自帶的,需要我們自己去實現。樂觀鎖是指操作數據庫
JAVA樂觀鎖、悲觀鎖實現
個數 自動 時間 update 頻繁 每次 調用 內部實現 字段 一、名詞解釋 1、悲觀鎖:認為每次對數據庫的操作(查詢、修改)都是不安全的,因此每次操作都會把這條數據鎖掉,直到本次操作完畢釋放該鎖 2、樂觀鎖:查詢數據的時候總是認為是安全的,不會鎖數據;等到更新數
MySQL中的行級鎖、表級鎖、頁級鎖
常用 一點 存儲引擎 rac 鎖定 方法 線程 加鎖 計算機 在計算機科學中,鎖是在執行多線程時用於強行限制資源訪問的同步機制,即用於在並發控制中保證對互斥要求的滿足。 在DBMS中,可以按照鎖的粒度把數據庫鎖分為行級鎖(INNODB引擎)、表級鎖(MYISA
MySQL中的鎖(表鎖、行鎖) MySQL中的鎖(表鎖、行鎖)
MySQL中的鎖(表鎖、行鎖) 鎖是計算機協調多個程序或純執行緒併發訪問某一資源的機制。在資料庫中,除傳統的計算資源(CPU、RAM、I/O)的爭用以外,資料也是一種供許多使用者共享的資源。如何保證資料併發訪問的一致性、有效性是所在有
【轉】【MySQL】MySQL中的鎖(表鎖、行鎖,共享鎖,排它鎖,間隙鎖)
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”),它假設多使用者併發的事務在處理時不會彼此互相影響,各事務能夠在不產生鎖的情況下處理各自影響的那部分資料。在提交資料更新之前,每個事務會先檢查在該事務讀取資料後,有沒有其他事務