Mysql讀寫鎖及事務 轉

讀寫鎖

同一用戶併發讀取同一條數據,不會出現什麼問題,因爲讀取不會修改數據,但是如果某個用戶正在讀取某張表,而同一時刻另一用戶正在修改這張表的id爲1的數據,會產生什麼後果?
答案是不確定的,讀的用戶可能會報錯退出,也可能讀到不一致的數據。 
解決這類經典問題的就是併發控制。在處理併發讀寫的時候,可以通過實現一個由兩種類型的鎖組成鎖系統來解決問題。這兩種鎖就是讀鎖(共享鎖)和寫鎖(排他鎖)。


讀鎖(共享鎖)是讀取操作創建的鎖。其他用戶可以併發讀取數據,但任何事務都不能對數據進行修改(獲取數據上的排他鎖),直到已釋放所有共享鎖。 
如果事務T對數據A加上共享鎖後,則其他事務只能對A再加共享鎖,不能加排他鎖。獲准共享鎖的事務只能讀數據,不能修改數據。

寫鎖(排他鎖)如果事務T對數據A加上排他鎖後,則其他事務不能再對A加任任何類型的封鎖。獲准排他鎖的事務既能讀數據,又能修改數據。

事務可以通過以下語句給sql加共享鎖和排他鎖: 
共享鎖:select …… lock in share mode; 
排他鎖:select …… for update;

共享鎖: 


排它鎖: 


讀鎖和寫鎖都是行級鎖,InnoDB的行鎖是通過給索引上的索引項加鎖來實現的,如果沒有索引,InnoDB將通過隱藏的聚簇索引來對記錄加鎖,InnoDB行鎖分爲3中情形: 
1. Record Lock:對索引項加鎖。 
2. Gap Lock:對索引項之間的“間隙”、第一條記錄前的“間隙”或最後一條記錄後的“間隙”加鎖。 
3. Next-key Lock:前兩種的結合,對記錄及其前面的間隙加鎖。 
InnoDB這種行鎖的實現特點意味着,如果不通過索引條件檢索數據,那麼InnoDB將對錶中的所有記錄加鎖,實際效果跟鎖表一樣。

事務

– ACID – 
原子性(Atomicity):整個事務操作要麼全部成功,要麼全部失敗。 
一致性(Consistency): 
隔離性(Isolation):一個事務所做的修改在提交之前,對其他事務是不可見的。也就是說事務互不影響。 
持久性(Durability):一旦事務提交,則其所做的修改就會永久保存到數據庫中。

隔離級別: 
read uncommit(讀未提交):在此隔離級別下,事務中的修改,及時沒有提交,對其他事務也都是可見的。會出現髒讀。 
read commit(讀已提交):事務中的修改,在提交之前,對其他事務是不可見的。會出現不可重複讀。 
repeatable read(可重複讀):mysql默認的隔離級別。同一個事務中 ,多次執行相同的select,結果是一致的。會出現幻讀。需要注意的是InnoDB和XtraDb存儲引擎通過MVCC(多版本控制)解決了幻讀的問題,準確來說是通過間隙鎖解決了幻讀的問題。 
serializable(可串行化):會在讀取的每一行上都加鎖,解決了幻讀,但不建議使用。

髒讀:事務可以讀取未提交的數據。 
不可重複讀:同一個事務,多次執行相同的select,結果不一樣。 
幻讀:事務A讀取某個範圍的記錄時,事物B在該範圍插入了新事物,事物A再次讀取該範圍內的記錄時,會產生幻行。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章