MySQL(五) — 鎖及事務

MySQL的鎖

Mysql不同的存儲引擎支持不同的鎖機制。比如,MyISAM和MEMORY存儲引擎採用的是表級鎖(table-level locking);InnoDB存儲引擎既支持行級鎖(row-level locking),也支持表級鎖,但默認情況下是採用行級鎖。

MySQL鎖分類

  • 表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。
  • 行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。
  • 頁面鎖(cap鎖,間隙鎖):開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。

僅從鎖的角度來說:
表級鎖更適合於以查詢爲主,只有少量按索引條件更新數據的應用,如OLAP系統。
行級鎖則更適合於有大量按索引條件併發更新少量不同數據,同時又有併發查詢的應用,如一些在線事務處理(OLTP)系統。

表鎖

MySQL中表級鎖有兩種模式:

  • 表共享讀鎖
  • 表獨佔寫鎖
用法
讀鎖

加鎖:lock table <表名> read

刪除鎖:unlock tables

寫鎖

加鎖:lock table <表名> write

刪除所:unlock tables

注意: 

  • 對MyISAM表的讀操作,不會阻塞其他用戶對同一表的讀請求。
  • 對MyISAM表的讀操作,不會阻塞當前session對錶讀,當對錶進行修改會報錯
  • 一個session使用LOCK TABLE命令給表f加了讀鎖,這個session可以查詢鎖定表中的記錄,但更新或訪問其他表都會提示錯誤;
  • 對 MyISAM表的寫操作,則會阻塞其他用戶對同一表的讀和寫操作;
  • 對 MyISAM表的寫操作,當前session可以對本表做CRUD,但對其他表進行操作會報錯。

行鎖

  • 共享鎖(讀鎖):當一個事務對某幾行上讀鎖時,允許其他事務對這幾行進行讀操作,但不允許其進行寫操作,也不允許其他   事務給這幾行上排它鎖,但允許上讀鎖。
  • 排他鎖(寫鎖):當一個事務對某幾個上寫鎖時,不允許其他事務寫,但允許讀。更不允許其他事務給這幾行上任何鎖。包括寫鎖。
用法
共享鎖

用法:lock in share mode

如:select * from table where 條件 lock in share mode;

排他鎖

用法:for update

如:select * from table where 條件 for update

 注意:

  • 兩個事務不能鎖同一個索引。
  • insert ,delete , update在事務中都會自動默認加上排它鎖。
  • 行鎖必須有索引才能實現,否則會自動鎖全表,那麼就不是行鎖了。

事務 

事務的特性

  • 原子性(atomicity):一個事務是一個不可分割的工作單位,事務中包括的諸操作要麼都做,要麼都不做。
  • 一致性(consistency):事務必須是使數據庫從一個一致性狀態變到另一個一致性狀態。一致性與原子性是密切相關的。
  • 隔離性(isolation):一個事務的執行不能被其他事務干擾。即一個事務內部的操作及使用的數據對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。
  • 持久性(durability):指一個事務一旦提交,它對數據庫中數據的改變就應該是永久性的。接下來的其他操作或故障不應該對其有任何影響。

數據庫事務隔離級別 

隔離性(isolation):隔離性要求一個事務對數據庫中數據的修改,在未提交完成前對於其他事務是不可見的。

事務併發會導致的問題:

  • 髒讀:事務A讀取了事務B更新的數據,然後B回滾操作,那麼A讀取到的數據是髒數據
  • 不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果 不一致。
  • 幻讀:系統管理員A將數據庫中所有學生的成績從具體分數改爲ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。
事務隔離級別 髒讀 不可重複讀 幻讀
讀未提交(read-uncommited)
讀已提交(read-commited)
可重複讀(repeatable-read)
串行化(serializable)

事務隔離級別爲可重複讀時,如果有索引(包括主鍵索引)的時候,以索引列爲條件更新數據,會存在間隙鎖間、行鎖、頁鎖的問題,從而鎖住一些行;如果沒有索引,更新數據時會鎖住整張表。

事務隔離級別爲串行化時,讀寫數據都會鎖住整張表。

 隔離級別越高,越能保證數據的完整性和一致性,但是對併發性能的影響也越大,對於多數應用程序,可以優先考慮把數據庫系統的隔離級別設爲Read Committed,它能夠避免髒讀取,而且具有較好的併發性能。

 

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