很久很久以前羞迷。應用APP只有一個界轩,功能都寫在一起。數據庫也只有一個衔瓮,所有的數據一致性問題也可以通過事務解決浊猾。轉賬交易當然是小菜一碟:
try{
transaction.begin();
db.execute(A-1000);
db.execute(B+1000);
transaction.commit();
}catch(Exception e){
transaction.rollback();
}
轉賬-單機.png
后來隨著應用的復雜,需要拆分出多個領域單獨部署應用和數據庫热鞍。比如A賬戶屬于借記卡領域葫慎,而B賬戶屬于信用卡領域单山。我們可以用分布式事務,也可以用補償機制:
轉賬-多機多庫 .png
NOTE:基于兩階段提交的分布式事務并不能100%保證一致性(比如在第二階段數據庫發(fā)生當機)幅疼。基于補償的最終一致性方案昼接,也有需要人工介入的情況爽篷。
上面的方案并不完善,沒有把考慮網絡問題考慮進來慢睡。在跨公司遠程訪問中逐工,網絡問題會比較突出和頻繁。
轉賬-遠程交互.png
在復雜的網絡情況下漂辐。除了成功和失敗泪喊,可能遇到沒有響應或超時的情況,這種情況下對方可能收到的請求也可能沒收到請求髓涯√惶洌可能處理了,也可能沒處理纬纪。如果重試一定次數后始終調用不成功蚓再,就需要人工介入。
轉賬-遠程同步.png
我們首先需要引入一張交易事務流水表包各,來記錄賬戶每次的變更情況和狀態(tài)摘仅。賬戶數據只保存最新的狀態(tài)∥食考慮到可能存在的重復提交娃属,在被調用方也需要流水表,來實現(xiàn)實現(xiàn)“冪等性”护姆。
其次考慮到轉賬可能失敗矾端,我們加入一個凍結資產的概念F,使得用戶可以明確看到這部分資金
當然交易可能是異步的卵皂,接收方可能需要做一些別的處理才返回
轉賬-遠程異步.png