鎖問題
通過鎖定機制可以實現事務的隔離性要求,使得事務可以並發地工作。鎖提高了並發,但是卻會帶來潛在地問題。不過好在因為事務隔離性地要求。鎖只會帶來三種問題,如果可以防止這三種情況地發生,那將不會產生並發異常。
1、臟讀
臟讀(Dirty Read),首先理解一下臟數據地概念。
臟頁:是指在緩沖池中已經被修改地頁,但是還沒有刷新到磁盤中,即數據庫實例內存中地頁和磁盤中的頁數據是不一致的。
臟數據:是指事務對緩沖池中行記錄的修改,並且還沒有被提交。
臟讀指的就是在不同事務下,當前事務可以讀到另外事務未提交的數據,簡單來說就是可以讀到臟數據。
臟讀現象的發生條件是需要事務的隔離級別為 READ UNCOMMITTED.
InnoDB存儲引擎默認的事務隔離級別為 REPEATABLE READ;
SQL Server 數據庫為 READ COMMITTED;
Oracle數據庫同樣也是 READ COMMITTED;
2、不可重復讀
不可重復讀是指在一個事務內多次讀取同一數據集合,發生了事務讀取不一致情況。
不可重復讀和臟讀的區別是:臟讀是讀到未提交的數據,而不可重復讀讀到的確是已經提交的數據,但是其違反了數據庫事務一致性(事務開始和完成時數據保持一致)的要求。
事務隔離級別 READ COMMITTED 解決不了不可重復讀是因為在MVCC 中查詢讀取的數據的快照版本數據是被鎖定行的最新一份快照數據。
事務隔離級別 REPEATABLE READ 可以防止不可重復讀是因為在MVCC中查詢的快照數據總是讀取事務開始時的行數據版本。
3、丟失更新(幻讀)
丟失更新時另一個鎖導致的問題,簡單來說其實就是一個事務的更新操作會被另一個事務的更新操作所覆蓋,從而導致數據的不一致。
要避免丟失更新發生,需要讓事務在這種情況下測操作變成串行化,而不是並行的操作。兩個事務同時查詢,更新數據,事務A查詢數據加上一個排他X鎖,事務B就需要等待事務A操作完成后才可以進行操作。
不可重復讀側重於修改
幻讀側重於新增和刪除
解決不可重復讀的問題只需要鎖住滿足條件的行,解決幻讀需要鎖表