程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> 並發情況下mysql拔出檢討計劃

並發情況下mysql拔出檢討計劃

編輯:MySQL綜合教程

並發情況下mysql拔出檢討計劃。本站提示廣大學習愛好者:(並發情況下mysql拔出檢討計劃)文章只能為提供參考,不一定能成為您想要的結果。以下是並發情況下mysql拔出檢討計劃正文


營業配景:
根本營業場景是如許的,要求數據(車輛vin信息)進入到接口中,須要先斷定其在數據庫中的狀況,假如庫中不存在該vin,或許該vin狀況位為“1(已完成)”,則履行一些檢討操作後,將數據拔出到數據庫中,此時新增vin狀況為0,挪用人工處置接口,非常鐘後前往成果,將狀況置為1。假如其狀況位為“0(正在處置)”則采納操作,前往提醒信息。
在單線程情況下,如許的營業沒有成績,但是當並發拜訪接口時,會湧現同時進入兩條vin雷同的要求AB,正常情形應當拔出一條A,采納一條B。但是並發情況下,B履行檢討狀況時A還沒有拔出,是以AB都進入到了數據庫中,數據就毛病了。

處理計劃一:
起首想到的是應用sql處置,對數據庫對應字段加獨一索引,包管分歧性。假如拔出反復的數據,則catch該異常,做出提醒。

ALTER tableName ADD UNIQUE [indexName] ON (tableColumns(length))

然則因為營業限制,vin在庫中是可以反復的,多條反復數據查詢最新,所以不克不及再vin上添加獨一索引。

處理計劃二:
應用mysql事務操作,將檢討能否存在和拔出作為一個事務停止處置,當檢討掉敗的時刻,不停止拔出。從網上搜刮了一下,年夜致思緒以下:

public static void StartTransaction(Connection con, String[] sqls) throws Exception { 
    try { 
      // 事務開端 
      con.setAutoCommit(false);  // 設置銜接不主動提交,即用該銜接停止的操作都不更新到數據庫 
      sm = con.createStatement(); // 創立Statement對象 

      //順次履行傳入的SQL語句 
      for (int i = 0; i < sqls.length; i++) { 
        sm.execute(sqls[i]);// 履行添加事物的語句 
      } 
      con.commit();  // 提交給數據庫處置 
      // 事務停止 

    //捕捉履行SQL語句組中的異常   
    } catch (SQLException e) { 
      try { 
        System.out.println("事務履行掉敗,停止回滾!\n"); 
        con.rollback(); // 若後面某條語句湧現異常時,停止回滾,撤消後面履行的一切操作 
      } catch (SQLException e1) { 
        e1.printStackTrace(); 
      } 
    } finally { 
      sm.close(); 
    } 
  }

然則如許現實上照樣沒有處理並發的成績,如許只是把兩個操作釀成了一個原子的sql操作,可以用於同時拔出兩條數據分歧性的情形,但其實不合適需求。

既然sql層面沒有處理成績,就斟酌從java的並發編程偏向處理。
處理計劃三:
java處理並提問題,起首想到的是應用內置鎖或許可重入鎖,根本語法以下:
·內置鎖:
因為是在Servlet中停止的處置,是以應用synchronized(this)直接處置營業代碼,使得並發情形下,只能有一個線程拜訪到該段營業代碼:

synchronized(this){
  //todo1:檢討vin能否存在
  //todo2:假如不存在拔出vin
}

·可重入鎖:
相當於更靈巧的內置鎖,在這裡與內置鎖根本雷同

public class DashengCallBack extends HttpServlet {
  private static ReentrantLock lock= new ReentrantLock();
  protected void doGet(HttpServletRequest request, HttpServletResponse response){
    lock.lock();
    try{
      //todo1:檢討vin能否存在
      //todo2:假如不存在拔出vin
    }finally{
      lock.unlock();
    }
  }
}

經由測試,這個計劃是可行的,終究沒有采取的緣由是由於直接應用這類方法加鎖,加鎖的代碼太多,影響效力。

處理計劃四:
設置一個查詢Map,拔出前存儲數據,拔出後刪除數據,代碼以下:

    ConcurrentHashMap<String, String> vinMap=new ConcurrentHashMap<String,String>();
    if(vinMap.containsKey(vin)){
      // todo1: vin 要求終了後, 從vinInRequestMap裡刪失落這個vinNo
      // todo2: 前往正在查詢
    }
    vinMap.put(vin, "");
    //todo3:拔出vin到數據庫
    vinMap.remove(vin);
  }

這個計劃根本知足了營業需求,獨一的成績是請求接口的更新時光要與營業時光錯開,不然更新接口會清空vinMap,招致庫中數據凌亂,湧現毛病。

以上就是本文的全體內容,願望對年夜家的進修有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved