資料來源和串連池

來源:互聯網
上載者:User

 

資料來源

 

  從接觸DBMS開始就在用資料來源(DataSource),它其中很重要的一個作用就是可以管理Connection,管理的方式也就是經常聽到的ConnectionPool。它的管理其實就是對DriverManager擷取Connection進行了封裝。

  下面就首先看看用DataSource來取代DriverManager來擷取Connection的好處:

  一般DataSource內部會用一個串連池來緩衝Connection,這樣獲得Connection速度很快,可以大幅度提高資料庫的訪問速度;通過它獲得的Connection都是已經被包裹過的(不是驅動原來的串連),他的close方法已經被修改(並不是真正的關閉)。我們只需和DataSource打交道,不會直接存取串連池。

 

串連池

 

  前面部落格講了,操作資料庫的一般步驟:

   1.註冊驅動

   2.建立串連

   3.建立執行sql語句的對象

   4.執行語句

   5.處理執行結果

   6.釋放資源

  上面的過程其實就是用戶端與DB伺服器互動的過程。這個過程就像兩個人隔著一條河想要交流一樣,其中最費時間的莫過於屬搭橋的過程了。上面第二步“建立串連”的過程也就是搭橋的過程了。

  所以,建立Connection就相當於建一座橋,是資料庫操作中最耗時的。所以用完以後就關掉是很浪費的。現在,建立完以後將它放到集合中(arrayList或linkList),用的時候從集合中取,用完了還放回集合中,這樣串連就可以複用了。就是用一個集合容器來緩衝Connection對象。

  上面說的集合其實就是串連池了,串連池可以理解成一個能夠存放Connection的Collection,有兩種形式,即arrayList或linkList。arrayList實際為一個數組,訪問速度很快;linkList為一個鏈表,增、刪速度比較快。而串連池中的Connection需要頻繁的增刪,所以採用linkList來作為Connection對象的容器集合。

  下面就用代碼類比一個DataSource內部的串連池:

import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.util.LinkedList;/** * @author-zhipeng */public class MyDataSource {private static String url = "jdbc:mysql://localhost:3306/jdbc";private static String user = "root";private static String password = "";private static int initCount = 5;private static int maxCount = 10;private int currentCount = 0;//建立一個LinkedList作為Connection的容器LinkedList<Connection> connectionsPool = new LinkedList<Connection>();//初始,建立5個Connection對象放到LinkedList中,用的時候從鏈表頭部取,不用了放到尾部public MyDataSource() {try {for (int i = 0; i < initCount; i++) {this.connectionsPool.addLast(this.createConnection());this.currentCount++;}} catch (SQLException e) {throw new ExceptionInInitializerError(e);}}//建立串連時就調用這個方法--從Connection鏈表容器頭部取一個public Connection getConnection() throws SQLException {//枷鎖-針對並行作業synchronized (connectionsPool) {//如果串連池(實際為LinkList)中還有Connection對象則取出一個if (this.connectionsPool.size() > 0)return this.connectionsPool.removeFirst();//如果串連池沒有(初始為5個)Connection對象,而請求串連數小於最大串連數,則建立一個新的Connectionif (this.currentCount < maxCount) {this.currentCount++;return this.createConnection();}//否則拋出異常,超過最大串連數,沒有串連可用throw new SQLException("已沒有連結");}}//關閉串連時就調用這個方法--不是真正的釋放串連,而是放到從Connection鏈表容器的尾部public void free(Connection conn) {this.connectionsPool.addLast(conn);}//建立Connection的根代碼private Connection createConnection() throws SQLException {return DriverManager.getConnection(url, user, password);}}

  從上面的代碼實現可知,如果超過Connection Pool的最大串連數(10個)則必然會因沒有串連可以使用而拋異常,下面就用代碼實驗一下:

/** * @author-zhipeng */public class TestConnectionPool {private static DataSource myDataSource = null;/** * 迴圈建立11個Connection,期間都不釋放(關閉) */public static void main(String[] args) throws Exception {for (int i = 0; i < 11; i++) {Connection conn = myDataSource.getConnection();System.out.println(conn);//JdbcUtils.free(null, null, conn);}}}

  然後運行,就會發現,當建立第11個的時候就會拋出異常:

 

 

 

  這也驗證了我們上面的實現。當然還可以進行一系列其它的測試,比如建立五個再釋放一個,然後再建立一個,這是你就會發現,Connection Pool的“隊列”結構。

 

總結

 

  上面簡單介紹了DataSource,和Connection Pool,並用代碼簡單類比了它的原理。這也是對舊知識的溫習和加深理解的過程吧。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.