1. 程式人生 > >MySQL可重復讀采坑記錄-對事務B進行更新時,事務A提交的更新會不會影響到事務B

MySQL可重復讀采坑記錄-對事務B進行更新時,事務A提交的更新會不會影響到事務B

但是 start clas 行數 通過 基礎上 transacti 隔離 delete

之前線上出現數據重復插入的問題,通過對問題進行排查發現該問題和MySQL的默認隔離級別-Repeatable Read(可重讀)有關系,可重復讀確保同一事務的多個實例在並發讀取數據時,會看到同樣的數據行。現在通過實驗,對問題進行下分析。

1.在終端A開啟事務A,查詢一下。

START TRANSACTION;
select spt.id,spt.audit_status,spt.is_deleted  from stat_point_task spt limit 5;

結果如下:

技術分享圖片

2.在終端B開啟事務B,進行同樣的查詢,可見結果和事務A中的結果是一樣的。

START TRANSACTION
; select spt.id,spt.audit_status,spt.is_deleted from stat_point_task spt limit 5;

技術分享圖片

3. 在事務A中,更新一下,將id=3的audit_status更新為3,查詢一下,發現更新成功,然後提交事務A;

update stat_point_task set audit_status=3,is_deleted=0 where id=3;
select spt.id,spt.audit_status,spt.is_deleted  from stat_point_task spt limit 5;
commit;


技術分享圖片

4. 此時,事務A更新了數據,並進行了提交,返回來再看事務B,在事務B中進行查詢,發現查詢到的還是事務A更新之前的數據。

/*再查詢下,因為可重復讀,發現查詢到的還是事務A更新之前的數據*/
select spt.id,spt.audit_status,spt.is_deleted from stat_point_task spt limit 5;

技術分享圖片

上面我們對MySQL的默認隔離級別可重復讀通過進行實驗進行了解釋,但是,此時我有一個問題,就是事務B在進行更新的時候,是在事務A更新後的基礎上更新,還是A更新前(和B通過查詢得到的數據保持一致)的基礎上更新,下面通過實驗來分析這個問題。

5.在事務B中更新數據,假設A的更新影響到事務B,在事務A的查詢結果中id=3的這條數據對應的audit_status為3,在事務B中的這條語句影響的行數應該為0,不會將audit_status設為4。

update stat_point_task set audit_status=4 where id=3 and audit_status=1;
select spt.id,spt.audit_status,spt.is_deleted from stat_point_task spt limit 5;

更新之後,再次進行查詢,發現id=3的這條數據對應的audit_status依然為1,說明事務A的更新影響到了事務B。

技術分享圖片

我們通過下面的語句再次驗證下 ‘對事務B進行更新時,事務A提交的更新影響到了事務B’ ,此時事務A中提交的更新已經將id=3的audit_status更新為3,雖然因為可重復讀,事務B中查詢到的id=3的audit_status為1,但是在事務B中進行如下的更新的時候,卻更新成功了,成功將audit_status更新為5.

update stat_point_task set audit_status=5 where id=3 and audit_status=3;
select spt.id,spt.audit_status,spt.is_deleted from stat_point_task spt limit 5;

技術分享圖片

綜上,

因為MySQL的可重復讀,對事務B進行查詢時,事務A提交的更新不會影響到事務B。

但是對事務B進行更新時,事務A提交的更新會影響到事務B。

-------------------------------------------

如有錯誤,請大家多多指正,不勝感激。

-------------------------------------------

MySQL可重復讀采坑記錄-對事務B進行更新時,事務A提交的更新會不會影響到事務B