Java 連接池的工作原理

jopen 13年前發布 | 20K 次閱讀 Java 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"); 
            } 
        } 
    } 
} 
... 

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

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


英文原文 , OSChina.NET翻譯

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!