1.背景
用多執行緒接收推送的訂單資料,把接收的訂單資料存到乙個表中,實現的需求是:如果接收的訂單訊息在資料庫中已經存在,那麼執行update操作;
如果沒有存在,那麼執行insert操作**邏輯:
if(oderid != null)else
執行緒啟動後,發現:資料庫表中有兩條oderid相同的記錄
通過檢視日誌發現:
兩個執行緒相差時間極端,各自收到了同乙個訂單的推送訊息,在執行資料庫insert或update時,都判斷出該訂單在資料庫表中不存在,所以都執行insert操作,造成資料庫表中有兩條orderid相同的記錄
2.解決方案
synchronized同步**塊即加同步鎖,synchronized同步**塊的功能:
1)、當a執行緒訪問物件的synchronized**塊的時候,b執行緒依然可以訪問物件方法中其餘非synchronized塊的部分
2)、當a執行緒進入物件的synchronized**塊的時候,b執行緒如果要訪問這段synchronized塊,那麼訪問將會被阻塞
if(oderid != null)else
else
} }
上面用synchronized同步**塊解決了在單點伺服器中涉及到的併發問題,但是synchronized同步**塊在部署到多台伺服器會失效,因為假設a機器在在執行資料庫insert,
判斷出資料庫中沒有某個訂單的資料,同時此刻b機器也判斷出沒有該訂單資料,兩台機器都進行insert操作,造成資料庫中有重複的訂單資料
3.多台伺服器相互之間的併發導致有重複的訂單資料問題解決
解決方案:
在資料庫層面,用unique唯一性約束來保證資料的資料庫表orderid的唯一性.
新增了唯一性約束後,假設a機器insert成功了,那麼b機器再insert的時候會違反唯一性約束,報invocationtargetexception這個異常,捕獲該異常後,進行update操作
if(oderid != null) else
else
catch
(exception e)
} }
}
**至
併發insert情況下會發生重複的資料插入問題
併發insert情況下會發生重複的資料插入問題 1.背景 用多執行緒接收推送的訂單資料,把接收的訂單資料存到乙個表中,實現的需求是 如果接收的訂單訊息在資料庫中已經存在,那麼執行update操作 如果沒有存在,那麼執行insert操作 邏輯 if 該訂單在資料庫表中存在 else 執行緒啟動後,發現...
併發insert情況下會發生重複的資料插入問題
1.背景 用多執行緒接收推送的訂單資料,把接收的訂單資料存到乙個表中,實現的需求是 如果接收的訂單訊息在資料庫中已經存在,那麼執行update操作 如果沒有存在,那麼執行insert操作 邏輯 if 該訂單在資料庫表中存在 else 執行緒啟動後,發現 資料庫表中有兩條oderid相同的記錄 通過檢...
什麼情況下會發生Full GC?
當呼叫system.gc 時,是建議jvm進行full gc,只是建議,不是一定會發生,但一般情況下,jvm也會進行full gc,進行full gc時會讓使用者執行緒暫停執行,建議能不使用此方法就不使用,讓虛擬機器自己去管理它的記憶體 老年代空間只有在新生代空間不足時,進入老年代空間或者建立了大物...