小猿最近很苦惱:明明加了分布式鎖,為什么并發(fā)還是會出問題呢?
故事從接到需求開始說起。
但實(shí)際的時序:
也就是說期望是這樣的執(zhí)行順序:
但實(shí)際的執(zhí)行順序:
分布式鎖和事務(wù),都是通過 AOP 來實(shí)現(xiàn)的,而 AOP 的執(zhí)行順序是根據(jù)切面的優(yōu)先級來的,而小猿的分布式鎖切面的優(yōu)先級比事務(wù)切面的優(yōu)先級低,所以就出現(xiàn)了上面的時序問題。
于是通過給分布式鎖的切面指定 Order 的方式,讓它的優(yōu)先級高于事務(wù)切面(注:Order 值越小,執(zhí)行優(yōu)先級越高),驗(yàn)證完沒問題后,就又高高興興地更新完版本,修復(fù)好歷史問題數(shù)據(jù)后回家了。
誰知道第二天一早,還是有極少量的用戶反饋賬戶余額不對的問題。
這次小猿就有點(diǎn)懵了,為什么還會出現(xiàn)這種情況呢?
經(jīng)過一番艱苦卓絕的排查,終于找到了問題所在:事務(wù)嵌套。
從前文中的示例代碼中可以看到,小猿的方法上加了事務(wù)注解 @Transactional(rollbackFor = Exception.class) 里,沒有指定事務(wù)的傳播行為,默認(rèn)是 Propagation.REQUIRED,也就是說如果當(dāng)前沒有事務(wù),就新建一個事務(wù);如果當(dāng)前有事務(wù),就加入到當(dāng)前事務(wù)中。
小猿自己寫的代碼里沒有在事務(wù)方法里嵌套調(diào)用這個方法的情況,但是同事寫的代碼里有,這樣就會導(dǎo)致前文的時序問題再次發(fā)生。
找到問題就好辦了,小猿將自己的方法上的事務(wù)傳播行為改成了 Propagation.REQUIRES_NEW,也就是說如果當(dāng)前沒有事務(wù),就新建一個事務(wù);如果當(dāng)前有事務(wù),就將當(dāng)前事務(wù)掛起,新建一個事務(wù)。
這次更新完版本后,小猿就再也沒有收到用戶反饋了,終于可以安心回家睡覺了。
在日常的開發(fā)過程中,如果涉及到并發(fā)和事務(wù),一定要多留幾個心眼,考慮周全,確認(rèn)以下要點(diǎn)是否都正確實(shí)現(xiàn):
本文鏈接:http://m.www897cc.com/showinfo-26-11218-0.html后端|一個分布式鎖「失效」的案例分析
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com