目前數據庫MySQL 並發事務下,在不同的隔離級別下,可能會出現四個問題.分別是:臟寫(Lost Update),臟讀(Dirty Reads),不可重復讀(Non-Repeatable Reads),幻讀(Phantom Reads)
數據庫的隔離級別分別是: 未提交讀(read uncommitted)、已提交讀(read committed)、可重復讀(repeatable read)、串行化(serializable)
1.查看MySQL目前的隔離級別,默認是 可重復讀
select @@transaction_isolation;
2.設置當前會話期間的事務隔離級別
set session transaction isolation level 事務隔離級別
set session transaction isolation level REPEATABLE READ;
我們現在來看下,如何復現不同隔離級別下的並發問題
1.臟寫:如果一個事務修改了另一個未提交事務修改過的數據,那就意味着發生了臟寫
由於臟寫問題過於嚴重,所以每一個事務隔離級別都防止了該情況發生
2.臟讀:一個事務已經更新一些數據到數據庫,但還沒有提交。另一個事務可以看到未提交的數據
該情況需在 隔離級別為:讀未提交下才會出現
這個時候發現,在右框開啟事務后,修改一條數據,沒有顯示commit, 在左邊就可以查詢到還沒有提交更新后的數據,這種情況就叫 臟讀!
3.不可重復讀:這種情況發生 在一個事務內多次讀同一數據。A事務查詢某條數據,該事務未結束時,B事務也訪問同一數據並進行了修改。那么在A事務中的兩 次讀數據之間,由於第二個事務的修改,那么第一個事務兩次讀到的的數據可能是不一樣的。
按照上面操作的步驟,可以重現不可重復讀的問題
讀已提交的隔離級別可以看到,避免了臟讀的出現,但是沒有避免不可重復讀的出現!
這次的事務隔離級別為 可重復讀,可以看到避免了 不可重復讀的並發問題!
4.虛讀 / 幻讀 : 事務A在操作一堆數據的時候,事務B插入了一條數據,A事務再次查詢,發現多了一條數據,像是幻覺。與不可重復讀類似,不同的是一個是修改,一個是新增或者刪除。
這個時候發現,在 可重復讀的隔離級別下,幻讀的情況也解決了?~
我們再看下 另外一種情況
這個時候 我們發現,在可重復讀的隔離級別下,並沒有完全解決幻讀這個問題,他只是解決了讀時候的幻讀問題, 沒有解決 寫 的時候的幻讀的問題