資料庫連接池的信息
資料庫連接池是用來保持與資料庫的連接,從而便於復用。
首先我們需要知道程序與資料庫是一個非常耗費資源的事情,尤其是程序與資料庫不在同一台機器上時,必須要開啟網絡的連接,以及雙方的互相驗證等等。如果沒有連接池的話,那麼每次查詢都要進行連接、驗證、關閉等操作,會非常的耗時耗力,連接池能夠保持連接,從而避免了多次建立連接的損耗。
上圖就是一個簡單的連接池的圖示信息,每次程序取得連接時其實是從連接池中取得連接,然後每次關閉的時候將此連接放入連接池中,然後連接池會自己根據一些規則定義連接在池子中保持多少、保持多久。
所以從上面描述我們可以知道在連接池中重要的就是兩個步驟了,什麼時候真正建立連接和什麼時候真正的關閉連接。
其實我們也能夠自己實現一個非常簡單的連接池。簡單的只需要幾步即可
public class MyDataSource implements DataSource {
private LinkedListdataSources = new LinkedList<>();
public MyDataSource(){
//一次性創建10個連接
for(int i = 0; i < 10; i++) {
try {
createConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public Connection createConnection(){
Connection con = null;
//1、加載Mysql連接
try {
Class.forName("com.mysql.jdbc.Driver");
//2、通過JDBC建立資料庫連接
con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/sys", "帳號", "密碼");
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
@Override
public Connection getConnection(){
if (dataSources.size()>0){
return dataSources.removeFirst();
}else {
return createConnection();
}
}
public void releaseConnection(Connection connection){
dataSources.add(connection);
}
}
當然了這只是非常簡單的一個連接池實現,完整的連接池要考慮的非常多。例如常用的連接池配置中的幾個參數,最大連接數量、空閒連接的數量、使用連接前驗證連接是否可用等等。
接下來我們用一個常見的異常來回顧一下常見的資料庫連接池的一些配置信息。
錯誤回顧
之前在開發過程中碰到一個異常,隨機出現的,異常信息如下
org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLRecoverableException: Closed Connection
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:296)
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:320)
at org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.java:214)
我們的項目使用的連接時DBCP,配置如下
經過網上查詢知道出現這個錯誤的原因是:程序要使用資料庫連接時會從線程池中拿出線程,但是此時連接池中從空閒連接中取出的線程在資料庫端被斷開了,在程序端並不知道此連接被斷開,所以會爆此錯誤。當然被斷開的原因有許多,例如資料庫端防火牆控制會清除連接了多久的空閒連接。
所以只需要在配置文件中加入validationQuery="select 1 from dual"這個參數即可,這個參數是在每次使用時都會驗證是否是有效連接。
或者也可以加上minEvictableIdleTimeMillis="3000000"此參數,表示空閒多久的連接會被在連接池中丟棄掉。此參數常常小於資料庫端防火牆配置的清除空閒連接的時間。
如果在DBCP中配置了minEvictableIdleTimeMillis參數,也要配置testWhileIdle="true"參數,此參數是開啟異步Evict的TimerTask定時線程進行控制。
常用的參數如下
作者:不學無數的程式設計師
連結:https://juejin.im/post/5cdcdd57f265da03a54c4285