背景:關於數據庫中的事務ACID以及隔離級別在面試筆試中常常被考。若是這種題再不會實在太惋惜了。因此要深刻總結html
髒讀和不可重複讀的區別:髒讀是某一事務讀取了另外一個事務未提交的髒數據,而不可重複讀則是讀取了前一事務提交的數據。面試
不可重複讀和幻讀的區別:都是讀取了另外一條已經提交的事務(這點就髒讀不一樣),所不一樣的是不可重複讀查詢的都是同一個數據項,而幻讀針對的是一批數據總體(好比數據的個數)。sql
不少人容易搞混不可重複讀和幻讀,確實這二者有些類似。但不可重複讀重點在於update和delete,而幻讀的重點在於insert。數據庫
若是使用鎖機制來實現這兩種隔離級別,在可重複讀中,該sql第一次讀取到數據後,就將這些數據加鎖,其它事務沒法修改這些數據,就能夠實現可重複讀了。但這種方法卻沒法鎖住insert的數據,因此當事務A先前讀取了數據,或者修改了所有數據,事務B仍是能夠insert數據提交,這時事務A就會發現莫名其妙多了一條以前沒有的數據,這就是幻讀,不能經過行鎖來避免。須要Serializable隔離級別 ,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這麼作能夠有效的避免幻讀、不可重複讀、髒讀等問題,但會極大的下降數據庫的併發能力。併發
因此說不可重複讀和幻讀最大的區別,就在於如何經過鎖機制來解決他們產生的問題。性能
上文說的,是使用悲觀鎖機制來處理這兩種問題,可是MySQL、ORACLE、PostgreSQL等成熟的數據庫,出於性能考慮,都是使用了以樂觀鎖爲理論基礎的MVCC(多版本併發控制)來避免這兩種問題。spa
行鎖防止別的事務修改或刪除,GAP鎖防止別的事務新增,行鎖和GAP鎖結合造成的的Next-Key鎖共同解決了RR級別在寫數據時的幻讀問題。htm
總結到很到位,還要繼續梳理blog
ps:數據庫中的兩段鎖,行鎖,表鎖,悲觀樂觀鎖。GAP(間隙鎖,也就是間隔鎖) 隔離級別和鎖的對應關係。