首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Tomcat JNDI 配置 Oracle DataSource 完整指南:連線池、防洩漏與實戰代碼

     編輯:Java 相關知識

配置層級選擇

  • Global (server.xml):全伺服器共享,適合多應用共用同一資料源。
  • Context 級別 (context.xml / META-INF/context.xml):單一 Web 應用專用,部署攜帶方便,**推薦生產環境使用**。

步驟 1:放置 JDBC 驅動

將 ojdbc8.jar (或對應版本) 放入 $CATALINA_HOME/lib/,**不要** 放在 WebApp 的 WEB-INF/lib (會導致類別載入器衝突)。

步驟 2:Context 級別配置 (META-INF/context.xml)

<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <Resource name="jdbc/oracleDS"
            auth="Container"
            type="javax.sql.DataSource"
            driverClassName="oracle.jdbc.OracleDriver"
            url="jdbc:oracle:thin:@//db-host:1521/SERVICE_NAME"
            username="app_user"
            password="app_pass"
            maxTotal="50"
            maxIdle="20"
            minIdle="5"
            maxWaitMillis="10000"
            testOnBorrow="true"
            validationQuery="SELECT 1 FROM DUAL"
            removeAbandonedOnBorrow="true"
            removeAbandonedTimeout="60"
            logAbandoned="true"
  />
</Context>

關鍵連線池參數說明 (DBCP2)

參數預設建議值說明
maxTotal850-100最大活躍連線數,視 DB 最大連線數與應用並發調整
maxIdle820-30池中保持的最大閒置連線
minIdle05-10池中最小閒置連線,預熱用
maxWaitMillis-1 (無限等待)10000取得連線最長等待毫秒數,防止無限阻塞
testOnBorrowfalsetrue借用前執行 validationQuery,確保連線有效
validationQuery無SELECT 1 FROM DUALOracle 專用驗證查詢,極輕量
removeAbandonedOnBorrowfalsetrue歸還時檢測並回收被遺棄連線 (未 close)
removeAbandonedTimeout30060認定為遺棄的秒數,視業務最長交易時間設定
logAbandonedfalsetrue記錄遺棄連線堆疊追蹤,定位洩漏程式碼

步驟 3:web.xml 宣告資源參考

<resource-ref>
  <description>Oracle DataSource</description>
  <res-ref-name>jdbc/oracleDS</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

步驟 4:Java 代碼查找與使用

@Resource(name = "jdbc/oracleDS") // 或手動 JNDI 查找
private DataSource dataSource;

public void doBusiness() {
    try (Connection conn = dataSource.getConnection();
         PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id = ?")) {
        ps.setLong(1, 123L);
        try (ResultSet rs = ps.executeQuery()) {
            // 處理結果
        }
    } catch (SQLException e) {
        // 記錄日誌、拋出業務異常
    }
}

常見坑點與排查

  • ClassNotFoundException: oracle.jdbc.OracleDriver:驅動 jar 未放入 $CATALINA_HOME/lib。
  • NameNotFoundException: Name [jdbc/oracleDS] is not bound:context.xml 路徑錯誤、Resource name 與 web.xml res-ref-name 不一致、Tomcat 版本差異 (5.5 vs 7/8/9/10 語法不同)。
  • 連線洩漏導致池耗盡:啟用 removeAbandonedOnBorrow=true + logAbandoned=true 觀察日誌堆疊,修正所有 try-with-resources 或 finally 區塊確實關閉資源。
  • 防火牆斷開長連線:配置 testOnBorrow=true + validationQuery,或啟用 testWhileIdle + timeBetweenEvictionRunsMillis 定期清理失效連線。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved