2010-07-05 26 views
1

我正在處理數據庫的Web前端。其目的是創建一個工具,供學生用來學習SQL,發出查詢並查看結果。在此之前,我一直在使用CLI。它的主要缺點是a)現在的學生更習慣於GUI;和b)當查詢返回一個非常寬的表時,很難閱讀,因爲它包裹了。我的網頁圖形用戶界面旨在解決這些缺陷。GWT RPC:跨多個請求使用相同的數據庫連接

我使用GWT作爲客戶端前端和PostgreSQL數據庫後端。 GWT通過由Jetty或Tomcat託管的Java servlet容器與數據庫進行通信。

使用GWT RPC機制發出簡單的查詢很簡單。不過,我堅持如何處理長期交易。爲了讓學生更好地理解事務的行爲方式,我需要他們能夠發出BEGIN語句,然後發出一個或多個查詢,然後執行COMMIT或ROLLBACK。我希望他們手動發佈BEGIN/COMMIT/ROLLBACK語句,這意味着交易可以活動多達幾分鐘。

(這是不打算成爲一個高性能的數據庫服務器。這是一個教學工具,所以我珍惜​​過速的用戶體驗。)

爲了實現這一點,我需要得到保證,通過在整個事務中,客戶端將被連接到相同的數據庫連接。使用傳統(無狀態)技術,數據庫連接不是短暫的就是合併。因此,不能確定跨多個查詢使用相同的數據庫連接。

恐怕我對Java servlets有點新,所以我有幾個問題。

首先,是否存在打開數據庫連接並在整個用戶會話中使用它的現有機制?

其次,我正在考慮創建一個servlet與之通信的輕量級服務器進程。服務器進程將使會話ID與活動數據庫連接相匹配,並將客戶端連接到適當的客戶端。因此,輕量級服務器本身維護數據庫連接並保持到用戶註銷 - 就像CLI一樣。這樣的事情已經存在嗎?

回答

3

Java servlet爲每個用戶會話保留一個HttpSession對象。每個會話對象都有一個字符串鍵映射,可用於將任意Java對象(例如SQL連接)附加到會話中。在你的情況下,我會檢索這樣的每個請求的連接對象:

// getThreadLocalRequest is a member of GWT's RemoteServiceServlet 
HttpSession session = getThreadLocalRequest().getSession(); 
Connection connection = (Connection)session.getAttribute("connection"); 

if (connection == null) { 
    // I'll leave it to you to implement createConnection 
    final Connection c = createConnection(); 
    connection = c; 

    session.setAttribute("connection", connection); 
    session.setAttribute("expiryListener", new HttpSessionBindingListener() { 
     public void valueBound(HttpSessionBindingEvent e) {} 

     // This method will be called when the user's session expires 
     public void valueUnbound(HttpSessionBindingEvent e) { 
      c.close(); 
     } 
    }); 
} 

// connection is ready to use! 
Statement statement = connection.createStatement();