XA規範
系統有一個事務管理器和資源管理器,每個資源管理器也要有預提交和提交兩個階段。例如DB需要有事務機制,消息隊列需要有消息的預發送、發送、回滾的處理能力。
兩段式過程
- 當應用向事務管理器預提交時,事務管理器向各個資源管理器預提交。
- 當應用向事務管理器提交時,事務管理器向各個資源管理器提交。
- 當應用向事務管理器回滾時,事務管理器向各個資源管理器回滾。
mysql本地事務
原子性、穩定性和持久性是通過redo 和 undo 日誌文件實現的,不管是redo還是undo文件都會有一個緩存我們稱之爲redo_buf和undo_buf。同樣,數據庫文件也會有緩存稱之爲data_buf。
undo 日誌文件
undo記錄了數據在事務開始之前的值,當事務執行失敗或者ROLLBACK時可以通過undo記錄的值來恢復數據。例如 AA和BB的初始值分別爲3,5。
- 事務開始
- 記錄AA=3到undo_buf
- 修改AA=1
- 記錄BB=5到undo_buf
- 修改BB=7
- 將undo_buf寫到undo(磁盤)
- 將data_buf寫到datafile(磁盤)
- 事務提交
通過undo可以保證原子性、穩定性和持久性
如果事務在F之前崩潰由於數據還沒寫入磁盤,所以數據不會被破壞。
如果事務在7之前崩潰或者回滾則可以根據undo恢復到初始狀態。
數據在任務提交之前寫到磁盤保證了持久性。
但是單純使用undo保證原子性和持久性需要在事務提交之前將數據寫到磁盤,浪費大量I/O。
redo/undo 日誌文件
引入redo日誌記錄數據修改後的值,可以避免數據在事務提交之前必須寫入到磁盤的需求,減少I/O。
- 事務開始
- 記錄AA=3到undo_buf
- 修改AA=1 記錄redo_buf
- 記錄BB=5到undo_buf
- 修改BB=7 記錄redo_buf
- 將redo_buf寫到redo(磁盤)
- 事務提交
通過undo保證事務的原子性,redo保證持久性。
5之前崩潰由於所有數據都在內存,恢復後重新衝磁盤載入之前的數據,數據沒有被破壞。
6,7之間的崩潰可以使用redo來恢復。
7之前的回滾都可以使用undo來完成。
具體redo/undo的流程和原理見:http://www.cnblogs.com/Bozh/archive/2013/03/18/2966494.html