java高併發經驗總結

   前不久,我做了一下java高併發場景的處理,在這裏總結一下:場景主要包括兩個方面:一個是減庫存,一個是記錄訂單。簡單分析一下業務:每個客戶端下單,服務器在數據庫上面都相應的執行兩個操作,第一步把庫存表某條庫存信息update更新一下,同時在訂單表中insert添加一個記錄某某客戶預定了某某商品的信息。這裏有個事務和行級鎖的問題。

update更新操作是需要行鎖的,也就是說update操作必須是串行化的。然而在高併發的情況下系統整體的處理能力纔是最重要的。我們來分析一下一個事務完成過程中對一條記錄加鎖的時間,從start  transaction開始,鎖定某記錄,第一步java向數據庫發出update指令,這期間伴隨着網絡延遲和GC的時間。update結束之後,java再次向數據發出insert指令,期間伴隨着網絡延遲和GC的影響。commit,然後釋放鎖。下一個請求開始重複執行。。。

我們分析一下可以看到其實這個過程效率不高,尤其是跨網段或者異地傳輸,導致非常大的網絡延遲,都將會導致java程序難以處理高併發。下面開始優化之路:

思路1:儘量讓每個情況佔據的鎖時間越短越好。既然update是加鎖的原因,那麼就先insert然後update,這樣每個事務佔據行鎖的時間減少了,單位時間內程序能夠處理的併發量就提交了。

思路2:減少網絡傳輸和GC的影響。直接在數據庫層面上把這個邏輯實現,可以在數據庫上面使用存儲過程完成一個事務的開始和結束。

思路3:使用隊列。使用redis等緩存做一個原子計數器,判斷庫存量。然後把訂單信息insert到數據表中。最後把減庫存的操作交給隊列,讓隊列異步去操作庫存表。

總結:善於把別人的經驗變成自己的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章