程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> HttpSession的線程安全問題及注意事項

HttpSession的線程安全問題及注意事項

編輯:關於JAVA

HttpSession session = request.getSession();
List<Product> list = session.getAttribute("productCart");
myService.save(list); // 保存購物車數據到數據庫

這個對象會被多次使用,也會被同一個用戶的多個頁面使用,所以他對於系統來說是線程不安全的。

比如用戶在從產品列表裡面選擇產品,這面選擇3種,他點了查看購物車

該用戶還開了另一個頁面,繼續選擇產品。

此時,在顯示購物車的頁面,有可能運行在一半時,其已經選擇的產品列表,並另一個頁面的操作修改了。所以顯示的產品數量有可能並不是3種。

因為session需要維持當前用戶的信息,所以其在多個線程裡是共享的。所以是線程不安全的。

不過,這個是表面現象,我們只要正確使用事務,保證數據的准確性,表面的問題可以不用管它。

我們可以把session裡面的數據另外保存到一個新的數據對象裡,這個對象不再因為session的改變而出現變動。這個對象傳遞給業務層進行事務處理,保證數據級別的准確。

千萬不要把session,或者 session裡面的對象直接傳遞給業務層,因為你的業務處理一半時,同樣可能出現session對象被改變的情況。有可能造成重要數據出現偏差。

舉例:

session 對應三個產品,

事務裡面循環了產品,並計算了總價格,

計算完畢,准備保存時,session變了,產品變成了4個。

此時開始保存。產品保存了4個,可總價格卻還是3個的。

出現了數據不一致。

修改後的例子

session 對應三個產品

重新生成一個產品對象數組,把session數據復制過來,然後傳遞給業務層

事務裡面循環計算總價格

計算完畢,此時session變了,但並不影響我們這個新的產品數組對象

保存,三個產品,價格也正確。

HttpSession session = request.getSession();
List<Product> list = session.getAttribute("productCart");
List<Product> listNew = new ArrayList<Product>();
Product pNew;
for(Product p : list){
 pNew = new Product();
 pNew.setProductId(p.getProductId());
 // 其它的復制參數的語句
 listNew.add(pNew); // 保存到新的列表裡面
}
myService.save(listNew); // 保存購物車數據到數據庫,這個是安全的

總結:

有些線程安全問題是很隱蔽的,等你出了問題,很可能根本不認為會是那裡出的問題。記住一點,Java裡面的對象傳遞的是對象的引用,只要2個地方用了相同的引用,則其它地方的變動,這一面也會變動。

原文:http://www.java2000.net/p9667

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved