JNDI 數據源配置的相關內容已經在 JNDI 資源文檔中詳細介紹過。但從 Tomcat 用戶的反饋意見來看,有些配置的細節問題非常棘手。
針對常用的數據庫,我們已經給 Tomcat 用戶提供了一些配置范例,以及關于數據庫使用的一些通用技巧。本章就將展示這些范例和技巧。
另外,雖然有些注意事項來自于用戶所提供的配置和反饋信息,但你可能也有不同的實踐。如果經過試驗,你發現某些配置可能具有廣泛的助益作用,或者你覺得它們會使本章內容更加完善,請務必不吝賜教。
請注意,對比 Tomcat 7.x 和 Tomcat 8.x,JNDI 資源配置多少有些不同,這是因為使用的 Apache Commons DBCP 庫的版本不同所致。所以,為了在 Tomcat 8 中使用,你最好修改老版本的 JNDI 資源配置,以便能夠匹配下文范例中的格式。詳情可參看Tomcat 遷移文檔。
另外還要提示的是,一般來說(特別是對于本教程而言),JNDI 數據源配置會假定你已經理解了 Context 與 Host 的配置偏好,其中包括在后者配置偏好中的應用自動部署的相關內容。
java.sql.DriverManager 支持服務提供者機制。這項功能的實際作用在于:對于所有可用的 JDBC 驅動,只要它們聲明提供 META-INF/services/java.sql.Driver 文件,就會被自動發現、加載并注冊,從而減輕了我們在創建 JDBC 連接之前還需要顯式地加載數據庫驅動的負擔。
但在 servlet 容器環境的所有 Java 版本中,卻根本沒法實現這種功能。問題在于 java.sql.DriverManager 只會掃描一次驅動。
Tomcat 自帶的阻止 JRE 內存泄漏偵聽器可以在一定程度上解決這個問題,它會在 Tomcat 啟動時觸發驅動掃描。該偵聽器默認是啟用的。只有可見于該偵聽器的庫(比如 $CATALINA_BASE/lib 中的庫)才能被數據庫驅動所掃描。
如果你想禁用該功能,那么一定要記住:首先使用 JDBC 的 Web 應用會觸發掃描,從而當該應用重新加載時會出錯;對于其他依賴該功能的 Web 應用來說也會導致出錯。
所以,假如應用的 WEB-INF/lib 目錄中存在數據庫驅動,那么這些應用就不能依賴服務提供者機制,而應該顯式地注冊驅動。
java.sql.DriverManager 中的驅動已經被認為是內存泄露之源。當 Web 應用停止運行時,它所注冊的任何驅動都必須重新注冊。
當 Web 應用停止運行時,Tomcat 會嘗試自動尋找并重新注冊任何由 Web 應用類加載器所加載的 JDBC 驅動。但最好是由應用通過 ServletContextListener 來實現這一點。