2014-06-24 154 views
0

我與連接池發生了一個問題,發送死數據庫連接。我使用jconn3(com.sybase.jdbc3)運行Glassfish 3.1.2.2以連接到Sybase 12.5。我們的組織每晚重新啓動一次,在此期間我們重新啓動Sybase服務器。當重啓過程中嘗試使用數據庫連接時,我的問題就會顯現出來。以下是產生我的問題的操作順序:無效連接返回到JDBC連接池 - GlassFish 3.1.2.2

  • Sybase已關閉以進行重新啓動。
  • 從池中請求連接。
  • DB操作按預期失敗。
  • 連接返回到處於關閉狀態的池。
  • Sybase已備份。
  • 從池中請求連接。
  • 由於「連接已關閉」異常,數據庫操作失敗。
  • 連接返回到池中
  • ,我實現了試圖從這種情況下恢復數據庫恢復單身。任何時候發生數據庫異常我都會調用一個jmx來暫停所有隊列,並在JDBC連接池上執行flushConnectionPool操作。如果數據庫連接仍未啓動,則進程會在10分鐘內設置一個要重試的計時器。雖然這個過程有效,但並非沒有缺陷。

    我意識到池中有一個設置,以便您可以在交付數據庫連接之前驗證數據庫連接,但出於性能方面的原因,我已經迴避了這一點。我的流程每天執行大約500萬次數據庫事務。

    我的問題是,有沒有人知道一種方法來避免首先將死連接返回到池?

    回答

    1

    你已經很好地概括了你的選擇。我們遇到了這個問題,午夜數據庫就會關閉。對我們來說,我們打開了連接驗證,但我們沒有交易量。

    Glassfish提供了一個自定義驗證選項,通過它可以指定一個類來進行驗證。

    缺省情況下,Glassfish的所提供的所有類都(你會看到他們在控制檯選項提供)是SQL語句是這樣的:

    SELECT 1; 
    

    語法不同數據庫之間的一點,SQL服務器使用'1',而對於Postgres,它只使用1。但意圖是相同的。

    網絡是每次嘗試獲得連接時都會花費額外的數據庫命中,但它確實是非常便宜的命中。但是,它仍然很受歡迎。

    但是你可以實現你自己的版本。它可以進行檢查,比如說,每10次請求一次,或者更不頻繁。如果您得到'1',請選擇(如果失敗,則失敗),否則返回「true」,從1到N(N = 10,20,100 ...)隨機選擇一個數字。但同時,請對其進行配置,以便在檢測到錯誤時清除整個池。清楚地調整這個,所以當你的數據庫在晚上出現故障(不知道你的系統在晚上有多忙)時,你有很好的機會發生這種情況。

    在峯值處理期間,您甚至可以「降低賠率」。 「如果時間在上午6點到下午6點之間,那麼賠率= 1000其他賠率= 100;如果(隨機(賠率)== 1){做出選擇...}」

    隨機選項不需要維護線程安全計數器。

    最後,它並不重要,您只需要及時注意數據庫已關閉,因此您可以要求GF放棄池。

    隨着數據庫出現,我可以確定地看到它在一開始就出現了一些顛簸,可能不止一次地刷新池,但這應該是無害的。

    不同的方式,你可以玩,但這是一個考慮的途徑。