MySQL可重復讀采坑記錄-對事務B進行更新時,事務A提交的更新會不會影響到事務B
之前線上出現數據重復插入的問題,通過對問題進行排查發現該問題和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