1. 事務的ACID
事務的ACID是指事務擁有的4個特性的首字母組合:atomicity(原子性), consistency(一致性), isolation(隔離性)和durability(持久性),
①atomicity(原子性):表示事務是一個不可分割的作業單元,要么在提交事務后所有更改成功,要么在回滾事務時撤消所有更改,不可以只執行其中的一部分操作,
②consistency(一致性):在每次提交、回滾之后或正在進行的事務,資料庫始終保持一致狀態,如正在跨多個表更新相關資料,則查詢看到的將是所有舊值或所有新值,而不是新值和舊值的混合,
③isolation(隔離性):事務在進行程序中相互隔離,他們不能互相干擾,也不能看到彼此的未提交資料,但可以通過修改隔離級別,查看其他事務正在處理的資料,
④durability(持久性):事務提交成功后,該事務所做的更改將會保存在資料庫中,
2. 并發讀取資料的問題
當事務讀取另一個事務已修改的資料時,可能會發生dirty read(臟讀)、non-repeatable read(不可重復讀)和phantom read(幻讀)之類的現象,
①dirty read(臟讀):當前事務讀取了另一個事務已更新但尚未提交的資料,后果就是另一個事務回滾了,此資料就為錯誤的無效資料,
②non-repeatable read(不可重復讀):當前事務讀取相同資料2次的程序期間,另一個事務修改了此資料并提交,造成當前事務讀取的2次結果不一致,
③phantom read(幻讀):當前事務讀取相同資料2次的程序期間,另一個事務插入了新行或更新一行以此造成當前事務讀取的2次結果不一致,看上不可重復讀與幻讀兩者差不多,但不可重復讀偏向于行的修改,幻讀偏向于行的新增,
3. 隔離級別
隔離級別是一種用于在多個事務同時進行更改和執行查詢時修改事務隔離性(isolation)的設定,權衡事務的保護以提高性能和并發性,
InnoDB儲存引擎支持的隔離級別有(從低到高): READ UNCOMMITTED(未提交讀)、 READ COMMITTED(已提交讀)、REPEATABLE READ(可重復讀) 和 SERIALIZABLE(可串行話),
3.1 READ UNCOMMITTED(未提交讀)
說明:為最低的隔離級別,表示當前事務可以讀取其他事務已修改但未提交的資料,這個級別會導致很多問題,通常,具有此隔離級別的事務僅執行查詢,而不執行插入,更新或洗掉操作,
3.2 READ COMMITTED(已提交讀)
說明:事務無法看到來自其他事務未提交的資料,簡單來講一個事務從開始直到提交前,所做的任何修改對其他事務而言是不可見的,
3.3 REPEATABLE READ(可重復讀)
說明:InnoDB的默認隔離級別,保證了在同一個事務內多次讀取同樣的記錄的結果為一致,
3.4 SERIALIZABLE(可串行化)
說明:為最高的隔離級別,表示事務一個接一個的串行執行,訪問同一資源時,后面的事務必須等待前面的事務操作完成后才能進行操作,
4. 總結
4.1 關系
不同的隔離級別解決臟讀、不可重復讀和幻讀的問題也不一樣,關系如下:
| 隔離級別 | dirty read(臟讀) | non-repeatable read(不可重復讀) | phantom read(幻讀) |
| READ UNCOMMITTED(未提交讀) | 未解決 | 未解決 | 未解決 |
| READ COMMITTED(已提交讀) | 已解決 | 未解決 | 未解決 |
| REPEATABLE READ(可重復讀) | 已解決 | 已解決 | 未解決 |
| SERIALIZABLE(可串行化) | 已解決 | 已解決 | 已解決 |
4.2 已提交讀與可重復讀的區別
兩者的主要區別在于不可重復讀的策略,
例如事務A讀取了2次行R1,在讀取2次期間事務B對行R1進行了修改,那么:
當隔離級別為READ COMMITTED(已提交讀)時:事務A讀取2次行R1的資料不一樣,
當隔離級別為REPEATABLE READ(可重復讀)時:事務A讀取2次行R1的資料一樣,
5. 參考資料
臟讀、不可重復讀和幻讀:https://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_read_phenomena
隔離級別:https://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_isolation_level
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/70548.html
標籤:MySQL
