1. 程式人生 > >關於多執行緒處理資料併發問題處理

關於多執行緒處理資料併發問題處理

資料量多時需要要多執行緒處理,尤其在叢集環境下很可能發生資源競爭的情況,此時就需要謹慎的對資料加鎖,如果加鎖出了問題,也是個麻煩事。

為安全考慮,一般處理這種問題有幾個步驟:

為此個業務加開關,如果出現問題,將開關關閉。但是遇到一些緊急問題,開關關閉會影響業務,這時就需要走以下邏輯:

1、資料量多,則資料取出後用執行緒池分批處理資料。

2、資料量不多,單執行緒就可以處理;建議建一個執行緒表專門處理執行緒鎖問題。這裡我們建一個asgin_thread的執行緒表,表中的欄位有id,SYNSTATE,VERSION,其中SYNSTATE為同步狀態,VERSION為版本號;其中的id是自己定義的,加鎖時也只加鎖這個表中的某一條資料,不能對業務表進行加鎖,將事務放到biz層,這樣的話整個biz層的邏輯同在一個事務內,加鎖才起作用。此處用樂觀鎖處理,將asgin_thread的單條資料加鎖後,統一業務層的其他邏輯都完成事務提交後鎖釋放。以下是程式碼:

while (running) {
      try {
        Thread.sleep(sleepTime);
      } catch (InterruptedException e) {
        log.error("異常:", e);
      }
      List<Bean> tasklist = null;
      try {
        tasklist = asignThreadBiz.update(loadCount);
        log.info("裝載已鎖定資料");
      } catch (Exception e) {
        log.error("執行緒出現鎖衝突,重新進行取資料....!",e);
        continue;
      } 
      
      if (tasklist != null && !tasklist.isEmpty()) {
        
        WorkThread<List<Bean>> ecThread = createWorkThread();
        ecThread.setTaskList(tasklist);
        threadPool.execute(ecThread);
      }
      // 狀態重製
      resetStatus();
    }

處理資料流程:

  asignDao.updateCount();  //執行緒表單條資料加鎖
    List<Bean> retlist = new ArrayList<Bean>();
    
    int retval = BeantDao.setLock(loadcount); //打標記
    if(retval > 0){
      retlist = beantDao.loadLock(); //取資料
    }

樂觀鎖:

AsginThread asgin = this.load(100000L);
asgin.setSynstate(asgin.getSynstate()+1);
this.saveOrUpdate(asgin);