MySQL事務以及隔離等級
前言:
我一直想不到一個好的標題應該怎麼寫。我想MySQL的一些重要的內容。我在兩次面試中都遇到過的,但直接用MySQL標題好像又不太貼切。乾脆就是所寫的內容吧。
MySQL事務:
transaction
Transactions are atomic units of work that can be committed or rolled back. When a transaction makes multiple changes to the database, either all the changes succeed when the transaction is committed, or all the changes are undone when the transaction is rolled back.
Database transactions, as implemented by InnoDB
, have properties that are collectively known by the acronym ACID, for atomicity, consistency, isolation, and durability.
See Also ACID, commit, isolation level, lock, rollback.
MySQL官網對事務的解釋。(提醒還在大一大二的師弟師妹,學號英語真的很重要,很重要,超級重要)
A(atomicity)原子性: 即事務要麼全部做完,要麼全部不做,不會出現只做一部分的情形,如A給B轉帳,不會出現A的錢少了,B的錢卻沒有增加的情況C(consistency)一致性: 指的是事務從一個狀態到另一個狀態是一致的,如A減少了100,B不可能只增加30。I(isolation)隔離性: 即一個事務在沒有完成資料的提交修改時,對其它事務是不可見的。當然這裡有個隔離等級的概念,在不同隔離等級下,這裡會有不同的表現形式D(durability)持久性: 一旦事務提交,則所做修改就會被永久儲存到資料庫中。四種隔離等級:
isolation level
One of the foundations of database processing. Isolation is the I in the acronym ACID; the isolation level is the setting that fine-tunes the balance between performance and reliability, consistency, and reproducibility of results when multiple transactions are making changes and performing queries at the same time.
From highest amount of consistency and protection to the least, the isolation levels supported by InnoDB are: SERIALIZABLE, REPEATABLE READ, READ COMMITTED, and READ UNCOMMITTED.
With InnoDB
tables, many users can keep the default isolation level (REPEATABLE READ) for all operations. Expert users might choose the READ COMMITTED level as they push the boundaries of scalability with OLTP processing, or during data warehousing operations where minor inconsistencies do not affect the aggregate results of large amounts of data. The levels on the edges (SERIALIZABLE and READ UNCOMMITTED) change the processing behavior to such an extent that they are rarely used.
See Also ACID, OLTP, READ COMMITTED, READ UNCOMMITTED, REPEATABLE READ, SERIALIZABLE, transaction.
Read Uncommitted(讀取未提交內容)
在該隔離等級,所有事務都可以看到其他未提交事務的執行結果。本隔離等級很少用於實際應用,因為它的效能也不比其他層級好多少。讀取未提交的資料,也被稱之為髒讀(Dirty Read)。
Read Committed(讀取提交內容)
這是大多數資料庫系統的預設隔離等級(但不是MySQL預設的)。它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變。這種隔離等級 也支援所謂的不可重複讀取(Nonrepeatable Read),因為同一事務的其他執行個體在該執行個體處理其間可能會有新的commit,所以同一select可能返回不同結果。
Repeatable Read(可重讀)
這是MySQL的預設交易隔離等級,它確保同一事務的多個執行個體在並發讀取資料時,會看到同樣的資料行。不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當使用者讀取某一範圍的資料行時,另一個事務又在該範圍插入入了新行,當使用者再讀取該範圍的資料行時,會發現有新的“幻影” 行。InnoDB和Falcon儲存引擎通過多版本並發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。
Serializable(可序列化)
這是最高的隔離等級,它通過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。簡言之,它是在每個讀的資料行上加上共用鎖定。在這個層級,可能導致大量的逾時現象和鎖競爭。
我這裡解釋一下 “讀寫提交內容” 和 “可重讀” 的區別。
假設有兩個事務 T1, T2
讀寫提交內容:
T1 insert了一條資料,T2此時看不到,等T1commit了以後,T2才看到了。這就造成了T2前後兩次select的內容不一致,也就造成了不可重讀的原因。
可重讀:
T1 insert了一條資料,T2此時看不到,等T1 commit了以後,T2還是看不到。等T2事務進行提交了以後,在進行select,發覺,臥槽,資料怎麼多了一條出來,感覺出現了幻覺,即“幻讀”;
MVCC機制:
多版本並發控制(Multiversion Concurrency Control)。MySQL預設隔離等級為Repeatable Read(可重讀)。那麼MySQL如何解決幻讀的。
就是利用MVCC機制。
什麼是多版本並發控制呢 ?其實就是在每一行記錄的後面增加兩個隱藏列,記錄建立版本號碼和刪除版本號碼,而每一個事務在啟動的時候,都有一個唯一的遞增的版本號碼。
只有read-committed和 repeatable-read 兩種交易隔離等級才能使用MVCC
read-uncommited由於是讀到未提交的,所以不存在版本的問題
而serializable 則會對所有讀取的行加鎖。
本文永久更新連結地址:https://www.bkjia.com/Linux/2018-03/151405.htm