一個Servlet線程安全問題實例

1.問題起源

幾年前開發的一個JavaWeb應用,用於課程實驗,同一時段內每次使用的用戶量大約20人左右,採用的技術框架爲Tomcat+Hibernate,功能僅限於簡單的增刪查改,並沒有複雜的邏輯。但是由於當時對JavaWeb只瞭解皮毛,所以根本沒有考慮到線程安全的問題,導致了後來的問題發生。

2.問題症狀

1.單機本地功能測試時完全沒有問題,多人同時使用時纔出現問題;
2.第一年實驗過程中未出現問題;
3.第二年實驗過程中出現唯一字段衝突問題,當時認爲是用戶誤操作造成數據衝突,因此直接刪除掉衝突數據再重新添加問題沒再出現;
4.第三年實驗過程中再次出現衝突問題與Hibernate的Session already closed異常,結合上一年的經歷與掌握的線程方面的知識,意識到很可能是代碼出了問題。

3.問題分析與解決方案

檢查代碼發現把Hibernate的Session對象放在了Servlet的成員對象裏並且使用時未同步,因此造成了線程安全問題,之後使用ThreadLocal包裝後得到解決。

4.其他收穫

(1)hibernate的SessionFactory的創建非常耗時,本身是線程安全的,一般一個應用創建一個單例對象即可,在每次創建Session時都重新創建SessionFactory會造成響應速度慢;
(2)hibernate持久化有幾種主鍵生成方式,對於單庫來說,使用數據庫自動生成方案是比較保險的,不必擔心多線程/進程情況下的衝突。

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