一次生产问题的复盘
問題描述
前段時間同事離職接手了一個支付功能,昨天業務反饋說支付以后,顯示仍然在支付中,但是部分訂單已經到賬了。情況比較詭異。
我們排查了數據以后,找到一筆比較正常的數據,讓可以重新試下,我們排查下問題,結果這個客戶一下批量支付,重新支付了一遍。問題越發嚴重了。
處理過程
我們首先在日志平臺上對日志進行排查,同時查詢支付數據,發現確實存在幾筆支付成功了。
于是就有了第一個問題:支付成功了,但是業務狀態沒有更新
繼續查看根據日志平臺trace,繼續查看日志,發現報null,但是沒有打印出來哪里報錯。
就出現了第二個問題:系統報錯,但是報錯信息被捕捉,導致日志中沒有stackTrace信息
然后查看數據庫數據,竟然又發現一個問題,就是有支付結果數據,但是沒有支付請求數據,
這就是第三個問題:支付成功了,但是請求數據都不存在了。導致這個問題的原因是直接在類上直接添加了@Transactional注解,循環報錯了以后,直接導致前面的事務都回滾了。
因為剛開始沒找到問題,想讓客戶重新點擊一筆試一下,結果客戶批量執行,導致剛才已經支付的業務又重新執行了一遍。這其實是剛才第一個問題,已經支付的業務狀態不能重復支付,要加上校驗。第四個問題:已支付的業務重復支付。
- 支付成功后,支付狀態沒有更新
- 支付成功的業務沒有記錄數據。
- 在查找問題的過程中沒有打印報錯信息
- 已支付的業務不能重復支付
系統優化
- 已經支付成功的數據需要立即修改業務支付狀態,不能等全部結束以后批量更新,因為如果有報錯,則不能繼續進行,但是已經支付的數據不再回滾。已支付的業務不再重復支付。
- 修改try catch錯誤打印方式,由getMessge()改為getStackTrace()
- 取消全局的@Transation,避免全局回滾。
經驗總結
- 已經支付的業務要立即進行更新支付狀態
- 同一個mergeId已經支付的賬戶不能重復支付。這是個很嚴重的問題。
- 把報錯信息打印出來
對于遍歷處理的功能,需要想到異常出現以后怎么辦?不能出現重復支付的情況。
總結
- 上一篇: 动态条形图(RunBargraph)用于
- 下一篇: JavaScript命名空间namesp