2010-06-21 155 views
14

按我的理解,JDBC連接池(在一個基本水平)的工作原理是這樣的:JDBC連接池:連接重用?

  1. 創建應用程序初始化過程中的連接,並將在緩存
  2. 提供給應用程序的需求,這些緩存的連接
  3. 一個單獨的線程保持連接池,執行類似的活動:已經使用
    • 丟棄連接(關閉)
    • 創建新的連接S和添加到緩存中保持連接

但是,每當我在一個JDBC連接池的討論聽到「連接複用」,我感到困惑的具體數量。連接重用何時發生?

這是否意味着連接池爲兩個不同的數據庫交互(不關閉它)提供相同的連接?或者,有沒有辦法在數據庫調用結束後繼續使用連接?

+0

只是好奇,但哪個連接池庫啓動單獨的線程管理池?我不認爲commons-dbcp這樣做 - 至少不是BasicDataSource。相反,我認爲連接檢查是在連接從池中檢出時完成的 – 2010-06-21 11:57:04

回答

12

連接池通過重新使用連接起作用。應用程序從池中「借用」連接,然後在完成時「返回」它。然後再將連接分發給應用程序的另一部分,甚至是另一個應用程序。

這是非常安全的,只要同一連接不是由兩個線程同時使用。

連接池的關鍵是避免在可能的情況下創建新的連接,因爲它通常是一個昂貴的操作。重用連接對性能至關重要。

10

連接池不會爲驅動程序提供實際的Connection實例,但會返回一個包裝。當你從一個Connection實例中調用'close()'時,它不會關閉驅動程序的Connection,而只是將打開的連接返回到池中,以便它可以被重用(參見skaffman的回答)。

+2

這取決於您使用的連接池的具體類型,例如, 'DataSource'或Commons DBCP-style。輕量級池可以返回原始的'Connection',並依賴不調用'close()'的應用程序代碼。 – skaffman 2010-06-21 09:46:21

+0

那麼,這是否意味着池中的JDBC連接必須依賴於Connection.commit()或Connection.setAutoCommit(true) - 可能這些調用是在Connection wrapper的over-ridden close()中進行的。 – haps10 2010-06-21 09:59:02

-1

我的理解與上面所述相同,並且,由於有錯誤,我有證據證明它是正確的。在我使用的應用程序中,有一個錯誤,即一個帶有無效列名的SQL命令。執行時拋出異常。如果連接已關閉,則下一次獲取並使用連接時,如果此時使用了正確的SQL,則會再次拋出異常,並且錯誤消息與第一次相同,儘管錯誤的列名甚至不會出現在第二個SQL。所以連接顯然正在被重用。如果在拋出第一個異常(由於列名錯誤)後連接沒有關閉,那麼下次使用連接時,一切正常。大概這是因爲第一個連接沒有被返回到池以供重用。 (此問題發生在Jave 1.6_30和連接到MySQL數據庫的情況下。)

+3

請避免使用文字牆,強烈建議在SO上格式化。 – Azulflame 2012-11-15 21:05:03

+0

除了格式化之外,考慮添加你發出的SQL命令,只要你得到的錯誤是爲了豐富你的答案 – 2012-11-15 21:06:30

1

連接池重用連接。 以下是apache dbcp如何工作的下劃線。

Connection poolableConnection= apacheDbcpDataSource.getConnection(); 

阿帕奇DBCP實現返回連接包裝是類型PoolableConnection的。

poolableConnection.close(); 

PoolableConnection.close()檢查,如果實際的底層連接被關閉或沒有,如果不是則返回這個PoolableConnection實例放入連接池(在這種情況下GenericObjectPool)。

if (!isUnderlyingConectionClosed) { 
      // Normal close: underlying connection is still open, so we 
      // simply need to return this proxy to the pool 
      try { 
       genericObjectPool.returnObject(this); //this is PoolableConnection instance in this case 
.... 
       }