1、事務的基本要素(ACID)mysql
一、原子性(Atomicity):事務開始後全部操做,要麼所有作完,要麼所有不作,不可能停滯在中間環節。事務執行過程當中出錯,會回滾到事務開始前的狀態,全部的操做就像沒有發生同樣。也就是說事務是一個不可分割的總體,就像化學中學過的原子,是物質構成的基本單位。sql
二、一致性(Consistency):事務開始前和結束後,數據庫的完整性約束沒有被破壞 。好比A向B轉帳,不可能A扣了錢,B卻沒收到。
數據庫
三、隔離性(Isolation):同一時間,只容許一個事務請求同一數據,不一樣的事務之間彼此沒有任何干擾。好比A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉帳。併發
四、持久性(Durability):事務完成後,事務對數據庫的全部更新將被保存到數據庫,不能回滾。性能
2、事務的併發問題spa
一、髒讀:事務A讀取了事務B更新的數據,而後B回滾操做,那麼A讀取到的數據是髒數據3d
二、不可重複讀:事務 A 屢次讀取同一數據,事務 B 在事務A屢次讀取的過程當中,對數據做了更新並提交,致使事務A屢次讀取同一數據時,結果 不一致。blog
三、幻讀:系統管理員A將數據庫中全部學生的成績從具體分數改成ABCDE等級,可是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺同樣,這就叫幻讀。事務
小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住知足條件的行,解決幻讀須要鎖表ci
3、MySQL事務隔離級別
事務隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
讀未提交(read-uncommitted) | 是 | 是 | 是 |
不可重複讀(read-committed) | 否 | 是 | 是 |
可重複讀(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
mysql默認的事務隔離級別爲repeatable-read
未提交讀
未提交讀的意思就是好比原先name的值是小剛,而後有一個事務B`update table set name = '小明' where id = 1`,它還沒提交事務。同時事務A也起了,有一個select語句`select name from table where id = 1`,在這個隔離級別下獲取到的name的值是小明而不是小剛。那萬一事務B回滾了,實際數據庫中的名字仍是小剛,事務A卻返回了一個小明,這就稱之爲髒讀。
已提交讀
按照上面那個例子,在已提交讀的狀況下,事務A的select name 的結果是小剛,而不是小明,由於在這個隔離級別下,一個事務只能讀到另外一個事務修改的已經提交了事務的數據。可是有個現象,仍是拿上面的例子說。若是事務B 在這時候隱式提交了時候,而後事務A的select name結果就是小明瞭,這都沒問題,可是事務A還沒結束,這時候事務B又`update table set name = '小紅' where id = 1`而且隱式提交了。而後事務A又執行了一次`select name from table where id = 1`結果就返回了小紅。這種現象叫不可重複讀。
可重複讀
可重複讀就是一個事務只能讀到另外一個事務修改的已提交了事務的數據,可是第一次讀取的數據,即便別的事務修改的這個值,這個事務再讀取這條數據的時候仍是和第一次獲取的同樣,不會隨着別的事務的修改而改變。這和已提交讀的區別就在於,它重複讀取的值是不變的。因此取了個貼切的名字叫可重複讀。按照這個隔離級別下那上面的例子就是:
串行化
上面三個隔離級別對同一條記錄的讀和寫均可以併發進行,可是串行化格式下就只能進行讀-讀併發。只要有一個事務操做一條記錄的寫,那麼其餘要訪問這條記錄的事務都得等着。
通常沒人用串行化,性能比較低,經常使用的是已提交讀和可重複讀。而已提交讀和可重複讀的實現主要是基本版本鏈和readView。而它們之間的區別其實就是生成readView的策略不一樣