2009-01-23 85 views
16

我有一個由大約15個方法組成的Java程序。而且,這些方法在程序的執行過程中被非常頻繁地調用。目前,我正在每種方法中創建一個新連接,並在其上調用語句(數據庫在網絡上的另一臺計算機上進行設置)。Java中有多少個JDBC連接?

我想知道的是:我應該在主方法中只創建一個連接,並將它作爲參數傳遞給所有需要連接對象的方法,因爲這會顯着減少程序中連接對象的數量而不是在每種方法中非常頻繁地創建和關閉連接。

我懷疑我現在的設計並不是非常有效地使用資源,並且考慮到這個程序未來可能會增長很多,還有很大的改進餘地。

回答

21

是的,您應該考慮重新使用連接,而不是每次都創建一個新連接。通常的程序是:

  • 猜測您的數據庫可以合理處理多少個同時連接(例如,從數據庫機器上的每個CPU開始2或3,直到你發現這太少或太多 - 它往往取決於你的查詢是如何磁盤綁定的)
  • 創建一個這個很多連接:本質上是一個類,您可以在每個方法的開始處要求「下一個空閒連接」,然後在每個方法結束時「傳回」池中的數據。您的getFreeConnection()方法需要返回一個(1)創建一個新的連接,直到您決定允許的最大連接數,或者(2)如果已經創建了最大連接數,請等待一個成爲免費連接
  • 我建議使用Semaphore類來管理連接;其實,我在我的網站很短的文章managing a resource pool with a Semaphore有一個例子,我想你可以適應你的目的

一對夫婦的實際考慮:

  • 爲了獲得最佳性能,你必須要小心當您沒有實際使用它來運行查詢時,不要「連接」連接。如果您從游泳池中連接一次,然後將其傳遞給各種方法,則需要確保您不會意外地執行此操作。
  • 不要忘了把你的連接返回到游泳池! (嘗試/最後是你的朋友在這裏...)
  • 在許多系統上,你的無法保持連接'永遠'打開:O/S會在一些最大時間後關閉它們。因此,在'返回連接池'方法中,您需要考慮長期存在的'退休'連接(構建用於記憶的某種機制,例如通過具有包裝對象圍繞一個實際的JDBC連接對象,您可以使用這個對象來存儲諸如此類的指標)
  • 您可能需要考慮使用預準備語句。
  • 隨着時間的推移,你可能需要調整連接池大小
+0

您能否詳細說明Prepared Statements如何在這裏提供幫助? – Epitaph 2009-01-28 00:26:04

8

您應該爲此使用連接池。

這樣,你可以問的連接,並釋放它,當你完成它,並返回到池中

如果另一個線程想要一個新的連接,以及一個在使用中,一個新的可能創建。如果沒有其他線程正在使用連接,則可以重複使用該連接。

通過這種方式,您可以以某種方式將應用程序保持原樣(而不是全部傳遞連接),並仍然正確使用資源。

不幸的是,第一類ConnectionPools在獨立應用程序中並不是很容易使用(它們是應用程序服務器中的默認應用程序)。可能是一個微容器(如Sping)或一個好的框架(如Hibernate)可以讓你使用它。

雖然從頭開始編寫代碼並不困難。

:)

This google search將幫助你找到更多有關如何使用一個。

滑過

+0

如果不考慮連接的「退休」爲什麼我們需要多個連接?一個單一的連接可以在任何地方使用rit;因爲聲明objs總是不同?當我們在應用程序中需要多個連接時? – 2012-09-17 18:11:10

0

如果您的應用程序是單線程的,或不從單個線程的所有數據庫操作,這是確定使用單連接。假設您因任何其他原因不需要多個連接,這將是最簡單的實現。

根據你的驅動程序,在線程之間共享連接也是可行的 - 如果你相信你的驅動程序不要說謊它的線程安全性,這也可以。有關更多信息,請參閱驅動程序文檔

通常,「Connection」下面的對象不能安全地在多個線程中使用,因此在線程之間共享ResultSet,Statement對象通常是不可取的 - 迄今爲止最好的策略是在創建它們的同一個線程中使用它們;這通常很容易,因爲這些對象通常不會保存太久。

3

許多JDBC驅動程序爲您執行連接池,因此在此情況下執行額外的池操作幾乎沒有優勢。我建議你檢查你的JDBC驅動程序的文檔。

另一種方法來連接池是

  • 有一個與同步訪問所有的數據庫訪問一個連接。這不允許併發性,但非常簡單。
  • 將連接存儲在一個ThreadLocal變量中(覆蓋initialValue())如果線程的固定數量很少,這很有效。

否則,我會建議使用連接池。