首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

GlassFish + JavaDB 首次啟動連線失敗?連線池 Ping 機制與啟動順序詳解

     編輯:程式設計疑難解答

現象描述

部署至 GlassFish 的 Java Web 專案使用 JavaDB (Derby),每次啟動伺服器與資料庫後,首次連線必須在管理主控台手動 Ping 連線池並重啟 JavaDB 程序才能成功,極度影響自動化部署。

根本原因

  1. 啟動順序競態:GlassFish 啟動連線池時,JavaDB 可能尚未完全就緒(端口開放 ≠ 服務就緒)。
  2. 連線池驗證機制:預設 validation-classname 或 validation-table 可能不匹配,導致首次驗證失敗。
  3. JavaDB Embedded 模式限制:若採用 Embedded 模式,同一 JVM 內只能有一個連線,可能與應用程式連線衝突。

解決方案

方案一:調整連線池屬性(推薦)

在 GlassFish 管理主控台 → Resources → JDBC → Connection Pools → [YourPool] 設定:

  • Steady Pool Size:設為 1(啟動時預建連線)。
  • Max Pool Size:視負載設定(如 32)。
  • Pool Resize Quantity:2。
  • Idle Timeout:300 秒。
  • Validation Method:table 或 auto-commit。
  • Validation Table Name:SYS.SYSTABLES(Derby 系統表,必定存在)。
  • Fail All Connections:勾選 On Failure。

方案二:確保啟動順序

# 啟動腳本範例 (Linux/Unix)
# 1. 先啟動 JavaDB (Network Server 模式)
nohup java -jar $DERBY_HOME/lib/derbyrun.jar server start -p 1527 > derby.log 2>&1 &

# 2. 等待端口就緒 (可加入健康檢查迴圈)
while ! nc -z localhost 1527; do sleep 1; done

# 3. 再啟動 GlassFish
asadmin start-domain domain1

方案三:程式碼層面重試邏輯

@Resource(name = "jdbc/MyDataSource")
DataSource ds;

public Connection getConnectionWithRetry(int maxRetry = 5, long intervalMs = 2000) {
    for (int i = 0; i < maxRetry; i++) {
        try {
            Connection conn = ds.getConnection();
            if (conn.isValid(2)) return conn;
        } catch (SQLException e) {
            log.warn("連線失敗,{}ms 後重試 ({}/{})", intervalMs, i+1, maxRetry);
            Thread.sleep(intervalMs);
        }
    }
    throw new RuntimeException("資料庫連線重試耗盡");
}

參考資源

總結

「首次 Ping 失敗」本質是服務就緒順序與連線池驗證策略不匹配。透過調大 Steady Pool Size、設定正確 Validation Table、確保 JavaDB 先於 GlassFish 就緒,即可實現「一次啟動、自動連線、零人工干預」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved