mysql事務特性是什么?
原子性(atomicity):一個事務必須視為一個不可分割的最小工作單元,整個事務中的所有操作要么全部提交成功,要么全部失敗回滾,對于一個事務來說,不可能只執行其中的一部分操作,這就是事務的原子性。
一致性(consistency):數據庫總是從一個一致性的狀態轉換到另一個一致性的狀態。
隔離性(isolation):一個事務所做的修改在最終提交以前,對其他事務是不可見的。
持久性(durability):一旦事務提交,則其所做的修改就會永久保存到數據庫中。此時即使系統崩潰,修改的數據也不會丟失。
實現:
持久性:通過 redo log來保證的
原子性:通過 undo log來保證的
隔離性:通過 MVCC 或鎖機制來保證的
一致性:通過持久性+原子性+隔離性來保證
事務隔離級別
讀未提交:
所有事務可以看到其它事務沒有提交的結果,會有很多
問題,如臟讀、幻讀、不可重復讀等。
讀提交:
大多數數據庫的默認隔離級別。滿足了隔離的簡單定義,一個事務只能看到其它事務提交事務做的改變,會引起不可重復讀。一個事務執行時,多次select,會看到不同結果。
可重復讀:
MySQL默認的隔離級別,確保同一個事務,在執行中,多次讀取操作數據,會看到同樣的數據行。但是有的數據庫會有幻讀問題。幻讀說的是"幻影"行,其它事務可能對表插入了新行。
串行化:
事務的最高隔離級別,通過強制事務排序,使之不能相互沖突,解決了幻讀的問題。在每個讀的數據上加共享鎖。可能會導致超時和鎖競爭。
MVCC:數據庫并發場景下的解決方案
MVCC是高并發版本控制器,用于數據庫中對數據庫的并發訪問。Mysql中InnoDB用這種方法來提高讀寫事務的并發性能、原因是MVCC是一種不采用鎖來控制事務的方式。同時還可以解決臟讀,幻讀,不可重復讀等事務隔離問題,但
不能解決更新丟失問題。
MVCC實現原理依靠:記錄中的3個隱含字段、undo log日志、Read View實現。
-
隱含字段:
-
undo log日志:
insert undo log:事務進行插入操作時產生、在事務回滾時需要,提交事務后可以被立即丟
update undo log:進行update、delete時產生的undo log、不僅在回滾事務時需要、在快照讀時也需要。所以不能隨便刪除,只有在快速讀或事務回滾不涉及該日志時,對應的日志才會被purge線程統一清除(purge類似jvm中的gc垃圾回收器)
- Read View(讀視圖): 一致性視圖。
在快照讀會產生Read View視圖,事務執行快照讀的那一刻,會生成數據庫快照,并且記錄。記錄當前活躍的事務ID(因為每個事務啟動開啟的時候,都會被分配一個ID,這個ID是遞增的,所以越新的事務,ID越大)。
簡單說,讀視圖是記錄快照讀那一刻所有記錄,下次快照時使用的還是同一個Read View所以其它事務修改。
而隔離級別中的RR(可重復讀)、和RC(提交讀)不同就是差在快照讀時
前者創建一個快照和Read View,并且下次快照讀時使用的還是同一個Read View所以其他事務修改數據對他是不可見的、解決了不可重復讀問題。
后者則是每次快照讀時都會產生新的快照和Read View、所以就會產生不可重復讀問題。
簡述MVCC實現原理:
InnoDB 每一行數據都有一個指向上一個版本數據在undo log日志里的位置指針。如果要執行更新操作,會將原記錄放入 undo log 中,并通過隱藏的回滾指針指向 undo log 中的原記錄。其它事務此時需要查詢時,就是查詢 undo log 中這行數據的最后一個歷史版本。
優點:MVCC:讀不加鎖,讀寫不沖突。
通過