Transaction Issues
資料庫交易在併發執行時可能發生的問題,這些問題可透過不同的隔離等級來防止。
Dirty Read
髒讀
指在一個交易讀取到另一個尚未提交(un-commit)的交易資料。如果那個交易最終被回滾(Rollback),則讀到的資料就是不準確的。
MySQL Demo
| Time | Transaction A | Transaction B |
|---|---|---|
| T0 | SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; | SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; |
| T1 | BEGIN; | BEGIN; |
| T2 | UPDATE employees SET salary = 600000.00 WHERE id = 1; | |
| T3 | SELECT * FROM employees WHERE id = 1; — 讀取到事務 A 尚未提交的修改 | |
| T4 | COMMIT; |
Phantom Read
幻讀
指在一個交易中,當它多次執行同一查詢時,由於其他交易插入、更新或刪除了符合查詢條件的行,導致每次查詢返回的結果不同。
詳細範例請參考:Gap Lock 防止幻讀
Non-Repeatable Read
不可重複讀
指在一個交易在多次讀取同一筆資料時,該資料的值因為另一個交易的更新而發生變化。
MySQL Demo
| Time | Transaction A | Transaction B |
|---|---|---|
| T0 | SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; | SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; |
| T1 | BEGIN; | BEGIN; |
| T2 | SELECT * FROM employees WHERE id = 1; — 第一次讀取數據 | |
| T3 | UPDATE employees SET salary = 6666.00 WHERE id = 1; | |
| T4 | COMMIT; | |
| T5 | SELECT * FROM employees WHERE id = 1; — 再次讀取,發現數據改變了 | |
| T6 | COMMIT; |