如果你不使用連接池,那么就沒有什么問題,一旦Connection關(guān)閉,數(shù)據(jù)庫物理連接就被釋放,所有相關(guān)Java資源也可以被GC回收了。
但是如果你使用連接池,那么請注意,Connection關(guān)閉并不是物理關(guān)閉,只是歸還連接池,所以PreparedStatement和ResultSet都被持有,并且實際占用相關(guān)的數(shù)據(jù)庫的游標(biāo)資源,在這種情況下,只要長期運行,往往就會報“游標(biāo)超出數(shù)據(jù)庫允許的最大值”的錯誤,導(dǎo)致程序無法正常訪問數(shù)據(jù)庫。
---
這個關(guān)不關(guān)和使用不使用conn pool沒有關(guān)系,一般操作是會是這樣,線程從外界獲取一個conn,然后創(chuàng)建自己地stmt,rs,然后執(zhí)行邏輯操作,然后將conn返回給pool。 如果程序員忘記手動關(guān)地話。當(dāng)這個線程執(zhí)行完以后,stmt,rs都成垃圾,當(dāng)他們被垃圾搜集地時候,gc會替我們把它們給關(guān)閉地。這就是很多代碼沒有關(guān)閉,仍然正常運行。
但是這樣會有一個潛在地問題。就是gc無法確定什么時候運行。如果free地內(nèi)存很多,很可能有些gc就不會被啟動,這樣stmt遲遲沒有被關(guān)閉,執(zhí)行一段時間會報錯。
所以健壯地代碼應(yīng)該手工把rs,stmt都關(guān)閉
---
Java連結(jié)Oracle常犯錯誤
1。只懂 createStatement,不懂關(guān)閉statement
2.。只懂 createStatement,不懂preparedStatement.
3 。只懂在sql里用to_date,甚至直接用String,不懂用 setDate()
---
我記得.我的程序中也出現(xiàn)過這種問題,
主要原因是我get Connection 對象后,這個connectin沒有被進(jìn)行關(guān)閉,
同時進(jìn)行出來的 preparedStatement 對象,不關(guān)閉也會出現(xiàn)這種問題,
而且,推薦這些數(shù)據(jù)庫操作的變量盡量用局部變量,現(xiàn)用現(xiàn)取,隨時關(guān)閉,而且放在finally{}中進(jìn)行關(guān)閉,比較保險
---
通常這樣的情形是你使用了超過DB設(shè)定同時可用的connection數(shù)量
你可以試試看下列方式:
1. 若你使用connection pool, 你可以將connection pool的max connection
數(shù)量降低看看, 同時檢查有無歸還connection
2. 若未使用conneciton pool, 你就該檢查一下, 你的connection在使用過後
有沒有關(guān)閉囉
另外一種情形是: 你的系統(tǒng)使用量真的很大, 所以同時150的DB connection
session是不夠的, 你就需要調(diào)整Oracle DB囉