業務上鎖的應用

業務場景

針對一個賠付工單(由底下小二發起),當金額數量大於必定值之後,針對這筆工單就會有層層審批(風控),先YY一個審批流「TL審批」--->「主管審批」--->「財務審批」.這裏就會存在3種權限「一審權限」「二審權限」「終審權限」,當這筆工單被小二提交之後就會給小二對應的TL建立一個審批任務,在主管的界面就能夠看到相應的審批任務,主管能夠點擊經過或者拒絕數據庫

實現

1.查詢任務,判斷當前角色是否有權限操做該筆任務,任務沒有完結等一系列校驗
    2.驅動狀態機更新工單狀態
    3.完結任務

異常場景

場景一
  1. 操做:主管瘋狂點擊經過按鈕3次(前提是按鈕點擊一次不會灰顯,就算灰顯也能夠經過模擬請求來實現)
  2. 異常狀況:三個點擊線程都運行完1,而後線程1驅動狀態機(經過 + 當前狀態:待TL審批)獲得的結果是待主管審批,緊接着線程2驅動狀態機(經過 + 當前狀態:待主管審批)獲得的結果是待財務審批,而後線程3再運行驅動狀態機(經過 + 當前狀態:待財務審批)獲得的結果是出帳成功(不考慮屢次完結任務會出現異常)
  3. 異常分析:在該場景中,只要角色擁有「一審權限」就能夠經過漏洞直接把該訂單審覈出帳
  4. 解決方案:線程

    • 細化狀態機中的每一個審覈操做
      1.查詢任務,查詢該筆任務對應當前操做類型(TL審批OR主管審批OR財務審批)
      ---這裏不單單是「經過」操做,判斷當前角色是否有對應操做權限
      2.根據當前操做類型+當前狀態驅動狀態機
      3.完結任務
    • 在查詢任務以前加一個全局鎖,針對這筆工單進行全局鎖定(更加優雅)

場景二

  1. 操做:一個角色同時擁有一審權限和二審權限,當他打開一個工單要進行一審,可是其它主管已經執行了一審的動做,而且更新了一些信息.由於該角色頁面沒有刷新獲取不到更新的信息,而後點擊了經過按鈕
  2. 異常狀況:點擊經過按鈕就至關於進行了二審,會形成該角色獲取不到最新信息而產生誤判
  3. 解決方案:在場景一增長一個全局鎖的前提下,能夠給頁面傳遞一個工單modifyTime,在全局鎖裏面判斷modifyTime是否一致,若是不一致說明該筆工單已經被更新了,能夠給用戶相應的提醒

其它

  1. 在業務中整個狀態機的流轉都是肯定的,因此爲了保證狀態流轉正確,因此在更新數據庫狀態的時候,須要帶上關於狀態的樂觀鎖UPDATE XXX SET status = XXX WHERE id = XXX AND from_status = XXX
  2. 若是使用的是全局鎖,那麼每一個操做工單的地方都須要加上相應的全局鎖
相關文章
相關標籤/搜索