mysql事務介紹

爲什麼要有事務?
事務廣泛的運用於訂單系統、銀行系統等多種場景。如果有以下一個場景:A用戶和B用戶是銀行的儲戶。現在A要給B轉賬500元。那麼需要做以下幾件事:

  1. 檢查A的賬戶餘額>500元;
  2. A賬戶扣除500元;
  3. B賬戶增加500元;
    正常的流程走下來,A賬戶扣了500,B賬戶加了500,皆大歡喜。那如果A賬戶扣了錢之後,系統出故障了呢?A白白損失了500,而B也沒有收到本該屬於他的500。以上的案例中,隱藏着一個前提條件:A扣錢和B加錢,要麼同時成功,要麼同時失敗。事務的需求就在於此。
    事務是什麼?
    與其給事務定義,不如說一說事務的特性。衆所周知,事務需要滿足ACID四個特性。
  4. A(atomicity) 原子性。一個事務的執行被視爲一個不可分割的最小單元。事務裏面的操作,要麼全部成功執行,要麼全部失敗回滾,不可以只執行其中的一部分。
  5. C(consistency) 一致性。一個事務的執行不應該破壞數據庫的完整性約束。如果上述例子中第2個操作執行後系統崩潰,保證A和B的金錢總計是不會變的。
  6. I(isolation) 隔離性。通常來說,事務之間的行爲不應該互相影響。然而實際情況中,事務相互影響的程度受到隔離級別的影響。文章後面會詳述。
  7. D(durability) 持久性。事務提交之後,需要將提交的事務持久化到磁盤。即使系統崩潰,提交的數據也不應該丟失。

MySql中的事務
事務的實現是基於數據庫的存儲引擎。不同的存儲引擎對事務的支持程度不一樣。mysql中支持事務的存儲引擎有innoDB和NDB。innoDB是mysql默認的存儲引擎,默認的隔離級別是RR,並且在RR的隔離級別下更進一步,通過多版本併發控制(MVCC,Multiversion Concurrency Control )解決不可重複讀問題,加上間隙鎖(也就是併發控制)解決幻讀問題。因此innoDB的RR隔離級別其實實現了串行化級別的效果,而且保留了比較好的併發性能。
事務的隔離性是通過鎖實現,而事務的原子性、一致性和持久性則是通過事務日誌實現。說到事務日誌,不得不說的就是redo和undo。
1.redo log
在innoDB的存儲引擎中,事務日誌通過重做(redo)日誌和innoDB存儲引擎的日誌緩衝(InnoDB Log Buffer)實現。事務開啓時,事務中的操作,都會先寫入存儲引擎的日誌緩衝中,在事務提交之前,這些緩衝的日誌都需要提前刷新到磁盤上持久化,這就是DBA們口中常說的“日誌先行”(Write-Ahead Logging)。當事務提交之後,在Buffer Pool中映射的數據文件纔會慢慢刷新到磁盤。此時如果數據庫崩潰或者宕機,那麼當系統重啓進行恢復時,就可以根據redo log中記錄的日誌,把數據庫恢復到崩潰前的一個狀態。未完成的事務,可以繼續提交,也可以選擇回滾,這基於恢復的策略而定。
在系統啓動的時候,就已經爲redo log分配了一塊連續的存儲空間,以順序追加的方式記錄Redo Log,通過順序IO來改善性能。所有的事務共享redo log的存儲空間,它們的Redo Log按語句的執行順序,依次交替的記錄在一起。如下一個簡單示例:
記錄1:<trx1, insert...>
記錄2:<trx2, delete...>
記錄3:<trx3, update...>
記錄4:<trx1, update...>
記錄5:<trx3, insert...>
2.undo log
undo log主要爲事務的回滾服務。在事務執行的過程中,除了記錄redo log,還會記錄一定量的undo log。undo log記錄了數據在每個操作前的狀態,如果事務執行過程中需要回滾,就可以根據undo log進行回滾操作。單個事務的回滾,只會回滾當前事務做的操作,並不會影響到其他的事務做的操作。**
以下是undo+redo事務的簡化過程
假設有2個數值,分別爲A和B,值爲1,2

  1. start transaction;
  2. 記錄 A=1 到undo log;
  3. update A = 3;
  4. 記錄 A=3 到redo log;
  5. 記錄 B=2 到undo log;
  6. update B = 4;
  7. 記錄B = 4 到redo log;
  8. 將redo log刷新到磁盤
  9. commit
    在1-8的任意一步系統宕機,事務未提交,該事務就不會對磁盤上的數據做任何影響。如果在8-9之間宕機,恢復之後可以選擇回滾,也可以選擇繼續完成事務提交,因爲此時redo log已經持久化。若在9之後系統宕機,內存映射中變更的數據還來不及刷回磁盤,那麼系統恢復之後,可以根據redo log把數據刷回磁盤。
    所以,redo log其實保障的是事務的持久性和一致性,而undo log則保障了事務的原子性。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章