本文主要介紹InnoDB的:鎖定讀和一致性非鎖定讀html
在一個事務中查詢數據時,普通的SELECT語句不會對查詢的數據進行加鎖,其餘事務仍能夠對查詢的數據執行更新和刪除操做。所以,InnoDB提供了兩種類型的鎖定讀來保證額外的安全性:mysql
SELECT ... LOCK IN SHARE MODE: 對讀取的行添加S鎖,其餘事物能夠對這些行添加S鎖,若添加X鎖,則會被阻塞。sql
SELECT ... FOR UPDATE: 會對查詢的行及相關聯的索引記錄加X鎖,其餘事務請求的S鎖或X鎖都會被阻塞。數據庫
當事務提交或回滾後,經過這兩個語句添加的鎖都會被釋放。安全
注意:只有在自動提交被禁用時,SELECT FOR UPDATE才能夠鎖定行,若開啓自動提交,則匹配的行不會被鎖定。session
MySQL官方文檔對弈一致性讀的定義:併發
A consistent read means that InnoDB uses multi-versioning to present to a query a snapshot of the database at a point in time.版本控制
就是說:一致性讀意味着InnoDB使用多版本控制來實現一個查詢,這個查詢所依賴的數據是基於某個時間點的數據庫快照
。code
注意:是數據庫的快照,而不是要查詢的那個表的快照。htm
在事務隔離級別設置爲READ COMMITTED和REPEATABLE READ時,默認狀況下InnoDB是經過一致性讀來處理SELECT語句的。一致性讀不會對它訪問的表設置任何鎖,所以,在一個表上進行一致性讀的同時,其餘session能夠隨意修改這些表。
一致性讀是使用基於時間點的快照信息來呈現查詢結果的讀取操做,而無論其餘事務在同一時間產生的變動。若是查詢的數據已被其餘事務改變,InnoDB會基於undo log的內容來重建最初的數據。
兩種事務隔離級別下,讀取的快照數據的區別:
該事務中第一個一致性讀創建的快照
。經過提交當前事務併發起一個新的查詢,能夠看獲得新的快照。本次一致性讀創建的快照
。(即,快照的時間點是基於本次一致性讀的時間點,也就是最新的數據)假設當前事務隔離級別爲REPEATABLE READ,當發出一個一致性讀(也就是一個普通的SELECT語句)時,InnoDB會根據這個查詢給此事務分配一個時間點。若其餘事務在此時間點以後刪除了一行並提交,那麼此事務不會看到其餘事務產生的影響(即,仍是會看到被刪除的行)。插入和更新操做也同樣。看以下實驗
create table test_cr( a int, b int )ENGINE=InnoDB DEFAULT CHARSET=utf8 mysql> select @@tx_isolation; +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+
實驗結果以下圖:
從圖中能夠看出,在REPEATABLE READ事務隔離級別下,session A的事務以第一次執行select語句的時間點生成了快照,以後的select查詢都是使用的此次快照數據。針對session B中事務做出的更新操做,若變動在session A中第一次select操做以前被commit,則session A的第一次select語句能夠看到session B中的變動,不然看不到session B中的變動。
參考: