分布式事務解決方案Seata原理剖析
稍后上傳我視頻分享地址:https://www.bilibili.com/video/BV11y4y1p7Ky/
默認是AT模式,我們就來剖析這AT模式到底是什么個原理
官網地址:http://seata.io/zh-cn/docs/overview/what-is-seata.html
整體機制是兩階段的提交
- 一階段:業務數據和回滾日志記錄在同一個本地事務中提交,釋放本地鎖和連接資源。
- 二階段:
- 提交異步化,非常快速地完成。
- 回滾通過一階段的回滾日志進行反向補償。
這是官網介紹,如果你看不懂,那么我接下來說人話,這次必懂
首先明確它的一些概念:
寫隔離
- 一階段本地事務提交前,需要確保先拿到 全局鎖 。
- 拿不到 全局鎖 ,不能提交本地事務。
- 拿 全局鎖 的嘗試被限制在一定范圍內,超出范圍將放棄,並回滾本地事務,釋放本地鎖。
這里的概念是十分重要的,基本上已經講清楚了它整個運作的原理
好,接下來我來說人話
背景
官網以兩個節點操作同一個數據庫為例進行說明,為了更加透徹的說清楚整個原理,我來以3個節點,分別操作3個數據庫為例(訂單,庫存,賬戶)
當我們進行下單的時候,會經過如下步驟
- 創建訂單
- 扣減庫存
- 扣減余額
任何一個環節出了問題,那肯定完蛋了,我想你絕對不想出現錢扣完了,但是卻提醒你還未支付吧,如果出現了,我想這個平台基本上沒人敢來了
按照官網寫隔離的定義,整個原理的過程如下(正常流程):
- 訂單表插入一條記錄
- 先獲取當前記錄的本地鎖,使用本地事務進行提交前嘗試獲取全局鎖,它是第一個執行的,因此一定能獲取的到全局鎖,然后提交本地事務,對於提交之前的數據進行undo_log的記錄,對於提交之后的數據也進行undo_log的記錄
- 庫存表進行更新
- 同樣的先獲取本地事務,再獲取全局鎖,然后提交
- 賬戶表進行更新
- 同樣的先獲取本地事務,再獲取全局鎖,然后提交
如果出現異常,如何處理?
如果更新庫存表的時候出現問題,則它開始回滾,並將回滾請求發送給TC,TC收到后,根據XID與Branch ID查找TC上各個分支上的事務,並根據記錄的undo_log與操作后的數據進行比較,如果相同則說明沒有被修改過,則反向補償(也就是將操作之前的數據再執行還原回去)【因為本地事務提交后,本地鎖就被釋放了,這期間可能被其他事務操作】,如果不一樣則需要人工處理或者采取其他措施
無論是否提交或者回滾,整個執行完之后都會異步的刪除undo_log記錄