2011-07-24 49 views
1

我正在使用Java Servlets的網站上工作,我的研究表明,最好每個用戶保持一個數據庫連接(而不是每次都只有一個連接坐在後臺或連接到數據庫)交易需要作出)。但是,我不知道如何完成這個任務。什麼我目前做的是在我的數據訪問對象類我有一個如何在Java Servlet應用程序上爲每個用戶創建一個數據庫連接?

private static Connection conn; 

,我有一個HTTPSessionListener - 上sessionCreated事件我連接到數據庫使用這種靜態「conn將」變量,並在sessionDestroyed事件我斷開在 「參數conn」 變量:

...在我的 「MySessionListener」 ......

public void sessionCreated(HttpSessionEvent sessionEvent) { 
    System.out.println("Session created!"); 
    DAO.connect(); 

} 

public void sessionDestroyed(HttpSessionEvent sessionEvent) 
{ 
    System.out.println("Session destroyed"); 
    String user = (String) sessionEvent.getSession().getAttribute("userid"); 
    if (user != null) DAO.signUserOut(user); 
    DAO.disconnect(); 
} 

現在有了這個問題是:

  1. 恐怕這種方式本質上會降低到只有一個人人共享的連接(而不是每個用戶的連接),只是我不時斷開連接,如果沒有用戶。正確?
  2. 如果多個用戶在線並且一個用戶關閉了他們的會話,他們將關閉每個人的連接,直到其他人開始會話併爲每個人創建一個新的連接,對不對?我無法對此進行很好的測試,因爲我在筆記本電腦上使用3臺瀏覽器在本地進行測試,但即使關閉了有我的網站的瀏覽器,該會話也不會立即死亡,而且我也不確定究竟發生了什麼。我所知道的是,有時候我會得到一個異常,說「連接關閉後不允許交易」。

回答

5

通常這是使用連接池實現的。您可以將其配置爲具有特定數量的可用連接,並且池管理打開和關閉連接。您的代碼只會從池中獲得可用連接,並在完成時返回。

看到這個(相當通用)Wikipedia article

一些衆所周知的池是DBCPC3P0

+1

警告:雖然鏈接的Oracle文章給出了有關連接池基本工作原理的正確基本概念,但提供的代碼示例不應用於生產!這是非常麻煩,不可擴展。而是使用servletcontainer提供的連接池設施。甚至Tomcat也帶有內置的連接池。 – BalusC

+0

@BalusC你是對的,這可能有點混亂,所以我現在刪除了這些引用。 –

+0

謝謝大家,我現在正在查看http://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.html,並將弄清楚如何使用Tomcat的連接池。會問我是否還有其他問題。謝謝! – iLoop

2

有在這裏吃兩個問題:

  • HTTP會話超時
  • 數據庫會話連接

你似乎混合兩種會話概念。

HTTP會話

您需要使用客戶端 - 服務器的HTTP機制,進一步熟悉。關閉瀏覽器不會關閉http會話。當你關閉瀏覽器時,你必須「關閉」代碼到你的頁面中。 「靠近」??絕對不是 - 在html/javascript中沒有關閉的東西。但是有onunload(以及onload)。

爲什麼javascript/html中沒有「onclose」?我認爲發明http/html的人對許多偶然事件都是偏執狂。也許,理所當然。也許,我們必須理解html/http發明的思想和動機。所以,你別無選擇,只能編造一個連鎖事件的連鎖反應。ONUNLOAD/ONLOAD是html頁面事件,而不是瀏覽器事件。整個html機制都是頁面驅動的,而不是瀏覽器驅動的因此,關閉瀏覽器時,會觸發瀏覽器上每個選項卡的onunload事件。

您將不得不使用onunload頁面通知服務器用戶有意關閉會話。否則,服務器將不得不依賴於會話超時值來結束會話。如果用戶在您未在onunload事件中編碼的頁面之一關閉瀏覽器,該怎麼辦?太糟糕了 - 這就是爲什麼我在每一頁上寫下了「在onunload上編造連鎖反應」的原因。這是非常煩人和令人煩惱的。

有時。特別是對於高度數學的servlet,服務器需要很長時間才能做出響應。然後客戶端頁面需要一個指示來區分仍然處理響應的服務器與服務器已經死機 - 在瀏覽器上執行會話超時。例如http://support.microsoft.com/kb/813827(如何更改Internet Explorer中的默認保持活動超時值)。

也許,服務器應該在瀏覽器頁面上戳一下,看看瀏覽器會話是否仍然存在。不。 Http是客戶端拉技術。服務器無法將響應推送到客戶端。爲什麼不?爲什麼這麼傻?你必須閱讀整個http/html心態/偏執狂才能理解。瀏覽器可以在服務器上戳,但反之亦然。

因此AJAX和彗星是發明/炮製的。模擬,假裝服務器推送。使用ajax,你有一些服務器在客戶端僞裝的方法。這就是你必須做的 - 使用ajax例如jquery或gwt。我更喜歡gwt。

如果客戶端計算機出現電源故障或操作系統遇到藍屏,或者瀏覽器進程突然終止,該怎麼辦?沒有機會觸發任何頁面的onunload事件。

數據庫連接會話

Alex的回答一針見血 - 連接池。但是,在某些情況下,我需要每個會話都有一個數據庫連接。嗯......我該怎麼做?是的,我將連接存儲爲會話屬性。因此,會話的數據庫連接數將盡可能多。這與你目前的工作基本上具有相同的效果。

爲一個無狀態(儘管cookies)和推定不穩定的客戶端開發有狀態的web應用程序需要謹慎。如果用戶在註銷後按下後退按鈕會怎麼樣?後退/前導頁面可能包含一個操作,導致服務器使用數據庫連接,在用戶按下後退按鈕之前,該連接已由註銷頁面關閉。或者,可能是服務器超時,原因是客戶端沒有在服務器上戳一段比會話保持活動超時值更長的持續時間。因此,在開發「多層」客戶端 - 服務器應用程序之前,您必須坐下來記錄所有意外事件,並且要充分了解http技術的思維/偏執。爲了設計你的應用程序,你需要用http的強迫性強迫感染你自己。

+0

謝謝。在你的答案的第一部分 - 關於HTTP會話 - 我幾乎可以肯定會話在瀏覽器關閉之後會暫停一段時間。但是你提醒我一個非常好的觀點 - 服務器不能戳客戶端。我不得不擔心會話在開放的時候會隨機死掉......你是否建議我服務的每個頁面都有一些ajax函數,它會週期性地向服務器推送一些無關緊要的東西,僅僅是爲了摳門而已? – iLoop

+0

「你是否建議每個頁面都有一些定期檢測服務器的ajax函數......?」閱讀彗星和長輪詢。 –

相關問題