支付寶轉賬過程併發交易引起的分布式死鎖問題

2021-07-10 22:11:44 字數 1840 閱讀 8189

最常見的一種場景: 支付寶賬號a向賬號b轉賬500元。 由於支付寶有幾億使用者,賬戶的儲存採用了分庫分表的方案, 賬號a和賬號b分別被儲存在不同的資料庫例項中

支付寶提供了一套柔性事務處理方案—基於二階段提交理論的tcc方案,這裡不再贅述,有興趣的同志參考

對於單筆交易,大致流程用偽**描述為:

try

confirm

//若confirm中某一步失敗or超時,則做下面的動作

cancel

上述過程中,在單筆交易中,是沒問題的

try

confirm

//若confirm中某一步失敗or超時,則做下面的動作

cancel

不難看出, 在兩筆交易幾乎同時執行的時候, 當交易1執行了step1鎖住a賬號再去鎖b賬號的時候,交易2可能正執行step3鎖住了b賬號然後要請求a賬號的資源。 這個時候死鎖就出現了。

結果就是兩筆交易都無法正常往下走,只能等待超時直至對方釋放資源。最終的結果可能是這兩筆交易都失敗, 然後再重新發起交易。 對於支付寶這樣的應用來說,這幾乎是不能容忍的。

好了,問題擺出來了,how to deal with it?

死鎖預防 使引起死鎖的必要條件不成立

– 資源排序,按資源序列申請

– 將所有併發事務排序,按識別符號或者開始時間

– 有死鎖危險的時候,事務退出已經占有的資源, 有兩種方法:

等待-死亡: 重啟較為年輕的事務, 較為年老的事務等待已經持有資源但是較為年輕的事務

受傷-等待: 年輕的等待年老的, 較年輕的重啟,而重啟事務並不一定是目前正在申請的事務

死鎖檢測

–檢測死鎖時迴圈等待的圈

多版本的概念

儲存已經更新資料的舊值

維護乙個資料項的多個版本

通過讀取資料項的較老版本來維護可序列性, 使得系統可以接受在其他技術中被拒絕的一些讀操作

寫資料項的時, 寫入乙個新版本,老版本依然保留

資料項x的多個版本

x1, x2, x3...
系統儲存的值

xi的值

read_ts(xi): 讀時標,成功讀取版本xi的事務的時標,·最大的乙個

write_ts(xi): 寫時標,寫入版本xi的值的事務時標

多版本規則

事務t發起write_item(x), xi具有x所有版本中的最高的write_ts(xi).

若write_ts(xi)<=ts(t) && read_ts(xi)>ts(t), 撤銷並回滾t

若write_ts(xi)<=ts(t) && read_ts(xi)事務t發起乙個read_item(x)操作,並且x的版本xi具有x所有版本中最高的write_ts(xi), 同時write_ts(xi)<=ts(t), 則將其xi返回給事務t, 並將read_ts(xi)的值設定為ts(t)和當前read_ts(xi)中較大的乙個

值 read write version

500 t1 t0 v1 //*事務t1執行read操作,讀取在其之前寫入的版本,這裡返回值是500*

800 t2 t2 v2 //*事務t2執行write操作*

支付寶轉賬過程併發交易引起的分布式死鎖問題

支付寶轉賬過程併發交易引起的分布式死鎖問題 問題背景 最常見的一種場景 支付寶賬號a向賬號b轉賬500元。由於支付寶有幾億使用者,賬戶的儲存採用了分庫分表的方案,賬號a和賬號b分別被儲存在不同的資料庫例項中 一般處理方案 支付寶提供了一套柔性事務處理方案 基於二階段提交理論的tcc方案,這裡不再贅述...

支付寶證書模式(轉賬給其他支付寶)

因為支付寶的加密方式要求資金類必須用證書方式加密,所以。1.去生成crt證書 2.開始開發 初始化 證書模式 vendor alipay.aop.aopcertclient 引入sdk aop new aopcertclient alipaycertpath 支付寶公鑰證書路徑 要確保證書檔案可讀 ...

支付寶開發轉賬介面

提現功能,需要呼叫支付寶的單筆轉賬介面。支付寶文件上邊一開始寫的是需要使用公鑰證書去請求,然而我的程式一開始寫的是使用公鑰金鑰去請求的。需要接入的話就必須修改原先的請求方式改成證書請求,修改方式會影響整個程式的支付寶請求環節。最後支付寶技術客服建議讓我去建立乙個新的應用來使用這個介面,於是終於可以開...