將 ojdbc8.jar (或對應版本) 放入 $CATALINA_HOME/lib/,**不要** 放在 WebApp 的 WEB-INF/lib (會導致類別載入器衝突)。
<?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>
| 參數 | 預設 | 建議值 | 說明 |
|---|---|---|---|
| maxTotal | 8 | 50-100 | 最大活躍連線數,視 DB 最大連線數與應用並發調整 |
| maxIdle | 8 | 20-30 | 池中保持的最大閒置連線 |
| minIdle | 0 | 5-10 | 池中最小閒置連線,預熱用 |
| maxWaitMillis | -1 (無限等待) | 10000 | 取得連線最長等待毫秒數,防止無限阻塞 |
| testOnBorrow | false | true | 借用前執行 validationQuery,確保連線有效 |
| validationQuery | 無 | SELECT 1 FROM DUAL | Oracle 專用驗證查詢,極輕量 |
| removeAbandonedOnBorrow | false | true | 歸還時檢測並回收被遺棄連線 (未 close) |
| removeAbandonedTimeout | 300 | 60 | 認定為遺棄的秒數,視業務最長交易時間設定 |
| logAbandoned | false | true | 記錄遺棄連線堆疊追蹤,定位洩漏程式碼 |
<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>
@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) {
// 記錄日誌、拋出業務異常
}
}
$CATALINA_HOME/lib。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 定期清理失效連線。