天天看點

資料庫幻讀,到底是個什麼奇葩問題?

簡單來說,你一個事務A,先發送一條SQL語句,裡面有一個條件,要查詢一批資料出來,比如 “select * from table where id>10”,類似這種SQL。然後呢,一開始查詢出來了2條資料,如下圖所示:

資料庫幻讀,到底是個什麼奇葩問題?

接着這個時候,别的事務B往表裡插入了幾條資料,而且事務B還送出了,如下圖所示,此時多了幾行資料出來:

資料庫幻讀,到底是個什麼奇葩問題?

接着事務A此時第二次查詢,再次按照之前的一模一樣的條件執行“select * from table where id>10”這條SQL語句,由于其它事務插入了幾條資料,導緻這次它查詢出來了4條資料,如下圖所示:

資料庫幻讀,到底是個什麼奇葩問題?

于是此時事務A開始懷疑自己的雙眼了,為什麼一模一樣的SQL語句,第一次查詢是10條資料,第二次查詢是12條資料?難道剛才出現了幻覺?導緻我剛才幻讀了?這就是幻讀這個名詞的由來。

幻讀指的就是你一個事務用一樣的SQL多次查詢,結果每次查詢都會發現查到了一些之前沒看到過的資料。

注意,幻讀特指的是你查詢到了之前查詢沒看到過的資料!此時就說你是幻讀了。

髒寫、髒讀、不可重複讀、幻讀,都是因為業務系統會多線程并發執行,每個線程可能都會開啟一個事務,每個事務都會執行增删改查操作。然後資料庫會并發執行多個事務,多個事務可能會并發的對緩存頁裡的同一批資料進行增删改查操作,于是這個并發增删改查同一批資料的問題,可能就會導緻髒寫、髒讀、不可重複讀、幻讀,這些問題。

是以這些問題的本質,都是資料庫的多事務并發問題,那麼為了解決多事務并發問題,資料庫才設計了事務隔離機制、MVCC多版本隔離機制、鎖機制,用一整套機制來解決多事務并發問題。