數據庫連接池dataesoruce pool深入理解


8.數據庫連接池的connection都是長連接的,以方便多次調用,多人連續使用。dataSourcePool
9.數據庫連接池中的連接,是在你用完之后,返回給數據庫連接池的,並不是close()掉,而是返回,以方便下次其他人使用。
10.數據庫連接池會自己通過代碼用心跳機制,保證隨時最小的連接connection數量同時存在,利用發送空數據的方式。
11.我們平常用的數據庫連接都是長連接的,因為我們每次都是從數據庫連接池中去拿connection的!!!db source里都是長連接!!
12.一個Connection實例,即對應底層一個TCP鏈接!一個Connection實例,即對應底層一個TCP鏈接!
13.connection不是線程安全的!Connection不是線程安全的,它在多線程環境中使用時,會導致數據操作的錯亂,特別是有事務的情況.connection.commit()方法就是提交事務,你
可以想象,在多線程環境中,線程A開啟了事務,然后線程B卻意外的commit,這該是個多么糾結的情況.
14.多個線程同用一個connection會不會提高效率,減少多次連接的消耗?答:不會,因為connection里,每個方法都是synchronized,都執行了同步。所以並不會提高效率。
如:
public int executeUpdate(){
synchronized(connection){
//do
}
}
15.菜鳥一般都是兩種方法使用connection:1。要么就是只用一個connection,多個線程都用一個connection。2.要么就是每個方法里面創建一個connection,每次調用都創建
一個connection。
這兩種都是效率低下的。
因為TCP鏈接的創建開支是昂貴的,當然DB server所能承載的TCP並發連接數也是有限制的.因此每次調用都創建一個Connection,這是不現實的;所以才有了數據庫連接池的出現.

16.數據庫連接池中保持了一定數量的connection實例,當需要DB操作的時候"borrow"一個出來,使用結束之后"return"到連接池中,多線程環境中,連接池中的connection實例交替
性的被多個線程使用.

17.數據庫連接池,怎樣歸還connection?
Connection connection = pool.getConnection();
//do
pool.release(connection);//歸還資源

18.2. 在使用dataSourcePool的情況下,一個線程中所有的DB操作使用的是同一個connection嗎??
比如線程A,依次調用了2個方法,每個方法都進行了一次select操作,那么這兩個select操作是使用同一個connection嗎?
第一感覺就是: dataSourcePool本身是否使用了threadLocal來保存線程與connection實例的引用關系;如果使用了threadLocal,那么一個線程多次從pool中獲取是同一個
connection,直到線程消亡或者調用向pool歸還資源..
如果在spring環境中(或者其他ORM礦建中),這個問題需要分2種情況:事務與非事務.
在非事務場景下,一切都很簡單,每一次調用,都是從pool中取出一個connection實例,調用完畢之后歸還資源,因此多次調用,應該是不同的connection實例.
public List<Object> select(String sql){
Connection connection = pool.getConnection();
//do
pool.release(connection);//歸還資源
}
在使用事務的場景下,情況就有所不同,開啟一個新事務的同時,就會沖pool中獲取一個connection實例,並將transaction和connection互為綁定,即此transaction中只會使用此
connection,此connection此時只會在一個transaction中使用;因此,在此事務中,無論操作了多少次DB,事實上只會是一個connection實例,直到事務提交或者回滾,當事務提交或
者回滾時,將會解除transaction與connection的綁定關系,同時將connection歸還到pool中
//開啟事務
public TransactionHolder transaction(){
Connection connection = pool.getConnection();
connection.setAutoCommit(false);
return new TransactionHolder(connection);
}

//執行sql
public boolean insert(String sql,TransactionHolder holder){
Connection connection = holder.getConnection();
//do
try{
//doInsert
return true;
}catch(Exception e){
holder.setRollback(true);
}
return false;
}

//提交事務
public void commit(TransactionHolder holder){
Connection connection = holder.getConnection();
connection.commit();
holder.unbind();//解除綁定
pool.release(connection);//歸還資源
}
在有事務的情況上,偽代碼可能就像上述例子.對於跨DB分布式事務,可能更加的復雜.

1.先打開一定數量的數據庫連接,當使用的時候分配給調用者,調用完畢后返回給連接池,注意返回給連接池后這些連接並不會關閉,而是
准備給下一個調用者進行分配。由此可以看出連接池節省了大量的數據庫連接打開和關閉的動作,對系統性能提升的益處不言而喻。
2.注意返回給連接池后這些連接並不會關閉
3.注意返回給連接池后這些連接並不會關閉
4.注意返回給連接池后這些連接並不會關閉
5.所以數據庫連接池都是長連接,數據庫連接池都是長連接。因為一個連接供給很多次調用。一個連接供給多人調用。當然是長連接了。
6.數據庫連接池會利用心跳機制,保證連接池中隨時都有最小數量的連接connection隨時存在,以隨時調用。它利用心跳機制,發送少量的空數據保持連接connection不會因不
發送數據而超過timeout,進而掛掉。

7.幾個概念:
最小連接--應用啟動后隨即打開的連接數以及后續最小維持的連接數。

 

本文不問思想借鑒http://blog.csdn.net/xwq911/article/details/49150043 感謝作者

創建一個數據庫連接池:

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);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM