數據庫連接池Data Source Pool的理解
1.數據庫連接池允許應用程序重復使用一個現有的數據庫連接,而不是再重新建立一個連接,避免了每個方法里new connection的耗費資源和時間。
2.數據庫連接池是在項目啟動時候初始化的,以方便程序運行時,隨時可以調用這些已經被創建好的connection。只需要getConnection()就好。
connection的建立、斷開都由連接池自身來管理。
3.創建connection是個很耗時的操作,所以建議在項目啟動的時候去創建connection。避免在方法里需要connection時再去new一個connection是很耗費時間的。
4.數據庫連接池,怎樣歸還connection?
Connection connection = pool.getConnection();
pool.release(connection);//歸還資源
5.程序啟動時候,是怎樣初始化一個數據連接池的?
答:spring啟動會自動ioc注入bean,相當於new已經配置好的連接池類。連接池類里面聲明了static的list,用以裝放connection。然后通過static代碼塊來將conection add進這個list。這樣,整個list就在new bean的時候,在加載這個連接池類的時,就先創建好了。后期程序運行時候,那些connection就已經存在了。
connection的理解
1.jdbc connection就是一個連接數據庫的TCP實例。
2.connection是個長連接的TCP。不像hTTP是個短連接的,每次都要3次握手才能建立。
3.connection長連接是提高了性能。不過還有一些細節的問題需要解決,即mysql發現一個鏈接長時間沒有執行查詢請求,就會自動斷掉這個連接。
4.具體多長時間后斷掉,有個timeout設置時間。通過sql:"show global variables like '%timeout';" 查看。
當鏈接已經失效了,仍然去執行查詢操作,一個明顯的表現形式就是提示:MySQL server has gone away
5.數據庫連接池通過心跳機制,每間斷一段時間發送空數據包來保持維護connection存活的。
6.長連接適用於要進行大量數據傳輸的情況,如:數據庫,redis,memcached等要求快速,數據量大的情況下。
7.我們平常用的數據庫連接都是長連接的,因為我們每次都是從數據庫連接池中去拿connection的!!!db source里都是長連接!!
8.mysql默認的connection timeout時間是8小時。這個可以通過my.ini配置文件修改。
9.connection不是線程安全的!Connection不是線程安全的,它在多線程環境中使用時,會導致數據操作的錯亂,特別是有事務的情況.connection.commit()方法就是提交事務,你
可以想象,在多線程環境中,線程A開啟了事務,然后線程B卻意外的commit,這該是個多么糾結的情況.
10.多個線程同用一個connection會不會提高效率,減少多次連接的消耗?答:不會,因為connection里,每個方法都是synchronized,都執行了同步。所以並不會提高效率。
如:
public int executeUpdate(){
synchronized(connection){
//do
}
}
11.菜鳥一般都是兩種方法使用connection:1。要么就是只用一個connection,多個線程都用一個connection。2.要么就是每個方法里面創建一個connection,每次調用都創建
一個connection。
這兩種都是效率低下的。
因為TCP鏈接的創建開支是昂貴的,當然DB server所能承載的TCP並發連接數也是有限制的.因此每次調用都創建一個Connection,這是不現實的;所以才有了數據庫連接池的出現.
創建一個數據庫連接池:
public class SimplePoolDemo { //創建一個連接池 private static LinkedList<Connection> pool = new LinkedList<Connection>(); //初始化10個連接 static{ try { for (int i = 0; i < 10; i++) { Connection conn = DBUtils.getConnection();//得到一個連接 pool.add(conn); } } catch (Exception e) { throw new ExceptionInInitializerError("數據庫連接失敗,請檢查配置"); } } //從池中獲取一個連接 public static Connection getConnectionFromPool(){ return pool.removeFirst();//移除一個連接對象 } //釋放資源 public static void release(Connection conn){ pool.addLast(conn); } }