標籤:
MYSQL的鎖
1. 共用鎖定,也就是讀鎖,可以通過select ... lock in share mode強制加鎖,預設select語句是不加鎖的
2. 獨佔鎖定,也就是寫鎖,可以通過select ... for update強制加寫鎖,預設情況下insert, update, delete語句加寫鎖
MYSQL鎖的粒度
1. 行鎖,鎖一行,並發高(因為衝突少),開銷小,會產生死結,innodb引擎
2. 表鎖,鎖全表,並發低(因為衝突多),開銷大,不會產生死結,myisam, memory引擎,所以myisam沒有事務,也是不會資料庫死結的,在執行SQL前做一次鎖定好所需資源,但是myisam可能會因為大量的表層級的寫鎖導致無法擷取到讀鎖從而對讀阻塞
3. 頁鎖,對杭鎖和表鎖的一種折中,鎖一批相鄰的記錄,在並發和開銷上介於行級鎖和表鎖中間,也會產生死結,bdb資料庫
Innodb儲存引擎
由於Innodb有MVCC,所以select ...的時候是不加鎖的,直接讀最新版本的資料
select語句強制指定鎖的時候回加鎖,還有就是insert, update, delete的時候要加鎖
交易隔離等級
交易隔離等級可以理解為描述了多個事務同時發生時候對資料的鎖定層級,這是在並發能力和交叉事務上表現的一種折中,在標準SQL中一共有四種事務隔離界別
四個隔離等級有兩個工程中幾乎不用
read uncommited,未提交讀
從名字上記憶就是,事務還沒提交,其他事務中就觀測到了資料的修改,沒人想用這個,針對別人還沒提交就讀取到的這種現象叫做髒讀
serialiazble,序列化
讀寫是衝突的,所以變成了串列,沒有並發,這個也沒人用
還有兩個隔離等級,是常用的
read commited,提交讀,簡稱RC隔離等級
這個層級解決了read uncommited髒讀的問題,對讀取的資料加讀鎖,讀完立刻釋放,對寫的資料加寫鎖,直到事務結束寫鎖才釋放。這樣就不會產生髒讀。但是會產生一次事務內寫鎖加鎖前讀取兩次讀取資料不一致的情況,這種不一致情況叫做不可重複讀取
repeatable read,可重複讀,簡稱RR隔離等級(MYSQL預設的交易隔離等級)
這個層級解決了read commited兩次讀取資料可能不一致的問題,解決的方法就是讀加讀鎖,直到事務結束才釋放,寫加寫鎖,直到事務結束才釋放。這樣就不會產生兩次讀的資料不一致,因為讀鎖的釋放時間增加了,保證了在讀的時候是不可以有人來改變資料的。
如果是通過簡單的行級鎖的機制來實現RR隔離等級,那麼在資料插入的時候會產生問題,比如事務1做一個範圍查詢,但是事務2在這個事務插入入了一條資料,並提交,事務1再做範圍查詢的時候回查詢到事務2新增的資料,這個也是一種兩次讀取資料不一致的情況,但是這個不叫不可重複讀取,叫做幻讀。
MYSQL在RR隔離等級下可以通過GAP鎖來解決幻讀,也就是加行鎖的時候不是只對某一行加鎖,而是根據索引,把相鄰的索引區間加鎖,這樣在相鄰區間上進行insert的時候,需要等待,這種GAP區間的大小也有可能最後變成鎖全表
mysql交易隔離等級