MySQL(26):事務的隔離級別出現問題之 幻讀


1. 幻讀

幻讀(Phantom Read)又稱為虛讀,是指在一個事務內兩次查詢中數據條數不一致,幻讀和不重復讀有些類型,同樣是在兩次查詢過程中,不同的是,幻讀是由於其他事務做了插入記錄的操作,導致記錄數有所增加。

例如:銀行在做統計報表時統計account表中所有用戶的總金額時候,此時總共有三個賬戶,總共金額為3000元,這時候新增了一個用戶賬戶,並且存入1000元,這時候銀行再次統計就會發現賬戶總金額為4000,造成了幻讀情況

 

2. 演示幻讀:

(1)首先我們設置b賬戶的隔離級別

b賬戶:由於前面將事務個隔離級別設置為可重復讀,這種隔離級別是可以避免幻讀的出現,因此需要將事務的隔離級別設置為更低,下面將事務的隔離級別設置為

Read Committed,具體語句如下:

set session transaction isolation level read committed;

上述語句執行完成之后,b賬戶事務的隔離級別為Read Committed

 

(2)演示幻讀:

b賬戶:首先在b賬戶中開啟一個事務,然后在當前事務中查詢賬戶的余額信息,查詢結果如下:

 

 

a賬戶:在對a賬戶進行添加操作之前,使用select語句查看當前a賬戶中的信息,執行結果如下:

接下來對a賬戶進行添加操作,a賬戶不用開啟事務,直接執行添加操作即可,具體語句如下:

insert into account(name,money) values('c',1000);

執行結果如下:

 

b賬戶:當a賬戶添加記錄完成之后,可以在b賬戶中再次查詢場合余額信息,如下:

通過對比b賬戶設置Read Committed隔離級別前后,發現第二次查詢數據時比第一查詢數據時候多一條記錄,這種情況並不是錯誤的,但可能不符合實際需求。需要注意的是,上述情況演示完成之后,將b賬戶中的事務提交。

 

 

3. 解決問題:

(1)重新設置b賬戶的隔離級別

b賬戶:為了防止出現幻讀,可以將b賬戶的隔離級別設置為Repeatable Read,具體語句如下:

set session transaction isolation level repeatable read;

上述的語句執行完畢之后,事務隔離級別設置為Repeatable Read

 (2)重新驗證是否出現幻讀

b賬戶:在b賬戶中重新開啟一個事務,並在該事務中查詢當前賬戶的余額信息,查詢結果如下:

 

 

a賬戶:對a賬戶進行添加操作之前,使用select語句查看當前的a賬戶的余額信息,執行語句結果如下:

接下來對賬戶a進行添加操作,在a賬戶中不開啟事務,直接執行添加操作,具體語句如下:

insert into account(name,money) values('d',1000);

執行結果如下:

 

 

b賬戶:當a賬戶的添加操作執行成功之后,再次查詢當前賬戶的余額信息,查詢結果如下:

 

對比b賬戶兩次查詢的結果,發現兩者都是一致的。並沒有出現重復讀取的情況,因此可以說明當前事務的隔離級別可以避免幻讀,最后還有使用commit語句提交當前事務,提交之后,b賬戶查詢結果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM