我們現(xiàn)在來模擬分布式事務(wù)還沒總體確認(rèn),還在中間狀態(tài)的情況:
我們可以看到,這三個(gè)表的數(shù)據(jù),還沒有發(fā)生改變,但undo_log多了三條數(shù)據(jù)。
SELECT * FROM `seata`.`t_account` LIMIT 0,1000;
SELECT * FROM `seata`.`t_order` LIMIT 0,1000;
SELECT * FROM `seata`.`t_stock` LIMIT 0,1000;
SELECT * FROM `seata`.`undo_log` LIMIT 0,1000;
--我們解析一下blog來看看數(shù)據(jù)到底是什么
SELECT CONVERT(rollback_info USING utf8mb4) FROM undo_log

undo_log

轉(zhuǎn)換后的blob
轉(zhuǎn)換之后,我們看到undo_log里面其實(shí)是有前后鏡像的。保存的是,事務(wù)操作之前和之后的數(shù)據(jù)切片。
而且t_order,t_account也有,一次購買操作添加了三條的undo_log日志。
前后鏡像作用:
前鏡像:用于回退之前的切片狀態(tài)。
后鏡像:用于確認(rèn)寫入的數(shù)據(jù)
可能你會(huì)有這個(gè)問題:如果多線程來買的時(shí)候會(huì)怎么樣?例如A先來買了2,B再來買2.庫存先扣減成998了,B的前后鏡像不就是:前998,后996啦?如果A回滾了,B的最終結(jié)果不就有問題了?
a:其實(shí)在買A的時(shí)候,庫存已經(jīng)鎖住了,B再來的時(shí)候要不等,要不fast fail。
總結(jié):AT模式就是用了動(dòng)態(tài)代理的方式,給全局事務(wù)方法創(chuàng)建了一個(gè)代理bean,代理對象在被調(diào)用的時(shí)候,會(huì)去undo_log創(chuàng)建對應(yīng)的前后鏡像,用于回滾和寫入的確認(rèn)。