支付寶轉賬過程併發交易引起的分布式死鎖問題
問題背景
最常見的一種場景: 支付寶賬號a向賬號b轉賬500元。 由於支付寶有幾億使用者,賬戶的儲存採用了分庫分表的方案, 賬號a和賬號b分別被儲存在不同的資料庫例項中
一般處理方案
支付寶提供了一套柔性事務處理方案—基於二階段提交理論的tcc方案,這裡不再贅述,有興趣的同志參考
對於單筆交易,大致流程用偽**描述為:
tryconfirm
//若confirm中某一步失敗or超時,則做下面的動作
cancel
上述過程中,在單筆交易中,是沒問題的
tryconfirm
//若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)值 read write version
500 t0 t0 v1
800 t2 t2 v2 //事務t2執行write操作
事務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方案,這裡不再贅述,有興趣的同志參考 對於單筆交易,大致流程用偽 描述為 try co...
支付寶證書模式(轉賬給其他支付寶)
因為支付寶的加密方式要求資金類必須用證書方式加密,所以。1.去生成crt證書 2.開始開發 初始化 證書模式 vendor alipay.aop.aopcertclient 引入sdk aop new aopcertclient alipaycertpath 支付寶公鑰證書路徑 要確保證書檔案可讀 ...
支付寶開發轉賬介面
提現功能,需要呼叫支付寶的單筆轉賬介面。支付寶文件上邊一開始寫的是需要使用公鑰證書去請求,然而我的程式一開始寫的是使用公鑰金鑰去請求的。需要接入的話就必須修改原先的請求方式改成證書請求,修改方式會影響整個程式的支付寶請求環節。最後支付寶技術客服建議讓我去建立乙個新的應用來使用這個介面,於是終於可以開...