並發情況下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,招致庫中數據凌亂,湧現毛病。
以上就是本文的全體內容,願望對年夜家的進修有所贊助。