Java 連接池的工作原理


什么是連接?

連接,是我們的編程語言與數據庫交互的一種方式。我們經常會聽到這么一句話“數據庫連接很昂貴“。

有人接受這種說法,卻不知道它的真正含義。因此,下面我將解釋它究竟是什么。[如果你已經知道了,你可以跳到它的工作原理部分]

創建連接的代碼片段:

String connUrl = "jdbc:mysql://your.database.domain/yourDBname"; Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection (connUrl); 

 

當我們創建了一個Connection對象,它在內部都執行了什么:

1.“DriverManager”檢查並注冊驅動程序,
2.“com.mysql.jdbc.Driver”就是我們注冊了的驅動程序,它會在驅動程序類中調用“connect(url…)”方法。
3.com.mysql.jdbc.Driver的connect方法根據我們請求的“connUrl”,創建一個“Socket連接”,連接到IP為“your.database.domain”,默認端口3306的數據庫。
4.創建的Socket連接將被用來查詢我們指定的數據庫,並最終讓程序返回得到一個結果。

為什么昂貴?

現在讓我們談談為什么說它“昂貴“。

如果創建Socket連接花費的時間比實際的執行查詢的操作所花費的時間還要更長。

這就是我們所說的“數據庫連接很昂貴”,因為連接資源數是1,它需要每次創建一個Socket連接來訪問DB。

因此,我們將使用連接池。

連接池初始化時創建一定數量的連接,然后從連接池中重用連接,而不是每次創建一個新的。

怎樣工作?

接下來我們來看看它是如何工作,以及如何管理或重用現有的連接。

我們使用的連接池供應者,它的內部有一個連接池管理器,當它被初始化:

1.它創建連接池的默認大小,比如指定創建5個連接對象,並把它存放在“可用”狀態的任何集合或數組中。

例如,代碼片段:

 ... 
  String connUrl = "jdbc:mysql://your.database.domain/yourDBname"; 
  String driver = "com.mysql.jdbc.Driver"; private Map<java.sql.Connection, String> connectionPool = null; private void initPool() { try { connectionPool = new HashMap<java.sql.Connection, String>(); Class.forName(driver); java.sql.Connection con = DriverManager.getConnection(dbUrl); for (int poolInd = poolSize; poolInd < 0; poolInd++) { connectionPool.put(con, "AVAILABLE"); } } ... 

 

2.當我們調用connectionProvider.getConnection(),然后它會從集合中獲取一個連接,當然狀態也會更改為“不可用”。

例如,代碼片段:

...
  public java.sql.Connection getConnection() throws ClassNotFoundException, SQLException {     boolean isConnectionAvailable = true;     for (Entry<java.sql.Connection, String> entry : connectionPool.entrySet()) {         synchronized (entry) {             if (entry.getValue()=="AVAILABLE") {                 entry.setValue("NOTAVAILABLE");                 return (java.sql.Connection) entry.getKey();             }             isConnectionAvailable = false;         }     }     if (!isConnectionAvailable) {         Class.forName(driver);         java.sql.Connection con = DriverManager.getConnection(connUrl);         connectionPool.put(con, "NOTAVAILABLE");         return con;     }     return null; } ... 

3.當我們關閉得到的連接,ConnectionProvider是不會真正關閉連接。相反,只是將狀態更改為“AVAILABLE”。

例如,代碼片段:

... 
public void closeConnection(java.sql.Connection connection) throws ClassNotFoundException, SQLException {     for (Entry<java.sql.Connection, String> entry : connectionPool.entrySet()) {         synchronized (entry) {             if (entry.getKey().equals(connection)) {                 //Getting Back the conncetion to Pool                 entry.setValue("AVAILABLE");             }         }     } } ... 

 

基本上連接池的實際工作原理就是這樣,但也有可能使用不同的方式。

現在,你可能有一個問題,我們是否可以創造我們自己的連接池機制?
 
我的建議是使用已經存在的連接池機制,像C3P0DBCP等。


免責聲明!

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



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