2009-09-21 57 views
2

背景:我正在使用hibernate對象進行數據庫訪問。
我的servlet的doGet裏面我有:併發訪問Java servlet的服務方法

Account account=getUserAccountHibernateObject(); 
doWorkOnAccount(account); 
decreaseAccountBalanceAndSaveToDB(account); 

由於servlet的允許併發訪問時,accountBalance真的搞砸了的時候。我有幾個問題:

  1. 這裏的最佳做法是什麼?我的線程是否應該實現SingleThreadModel來防止併發訪問?或者同步doGet中的所有內容?
  2. 我應該做以下事情嗎?在hibernate中做什麼是正確的?

    Account account=getUserAccountHibernateObject(); 
    doWorkOnAccount(account); 
    account=getUserAccountHibernateObject(); 
    decreaseAccountBalanceAndSaveToDB(account); //also synchronize this method. 
    

編輯: 試探性的解決方案: 多虧了答案提供的鏈接,我想我需要跨越整個servlet請求DB交易:

 
beginTransaction(); 
try{ 
Account account=getUserAccountHibernateObject(); 
doWorkOnAccount(account); 
decreaseAccountBalanceAndSaveToDB(account); 
commitTransaction(); 
}catch(Exception ep){ 
    rollBackTransaction(); 
}finally{ 
    closeSession(); 
} 

如果有任何休眠/ db guru那裏有什麼問題,請告訴我。

+1

Servlet可以同時使用,但不是它的service()局部變量。所以servlet併發性在這裏不是問題。我懷疑你的問題是缺少數據庫事務或不正確的鎖定對象。 – 2009-09-21 18:25:06

回答

0

我的猜測是,你的代碼的一部分存儲或訪問靜態變量的數據或其他不正確的線程安全。

我一直在研究相對較大的webapps,這些webapps從來不需要提供過度的同步(並且肯定不求助於單線程訪問)以避免併發問題。

很難提出什麼具體的解決方案,而不會看到更多的事情是如何佈置的。