1. 程式人生 > >java高併發經驗總結

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到資料表中。最後把減庫存的操作交給佇列,讓佇列非同步去操作庫存表。

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