6. Connection has already been closed 數據庫連接被關閉


生產上Tomcat出現 Connection has already been closed.問題,但是在uat測試是好的!

遇見兩次:

1.某個程序dao中執行邏輯異常復雜,有時候需要執行一分多鍾,uat正常執行,生產上個別執行時間長的會出現Connection has already been closed!

2.某程序在service中注入dao,業務邏輯中獲取一批數據放在list中遍歷,每遍歷一次用dao直接調用方法,大概四五個dao的方法,過一會出現Connection has already been closed!

問題根本原因:

1.小伙伴配置時,會添加以下連接配置參數

removeAbandoned="true"

removeAbandonedTimeout="60"(removeAbandonedTimeout”(默認300秒)
logAbandoned="true"

 有時候代碼中會有從連接池中獲取連接使用后忘記了連接的關閉,這樣連池的連接就會逐漸達到maxActive直至連接池無法getConnection。

連接池一般提供檢查功能,即設置了removeAbandoned="true",連接就可以自動回收。

連接自動回收判斷標准:

<!--是否回收已經超過 removeAbandonedTimeout 設置的無效連接,自動回收超時連接
          啟動機制:getNumActive() > getMaxActive() - 3 和 getNumIdle() < 2 
          假設maxActive=20,而當前18個活動連接,1個空閑連接,機制將會啟動
          但是只有在活動連接沒有使用的時長超過“removeAbandonedTimeout”(默認300秒)上述配置為60s,的連接將被回收-->

 

配置logAbandoned="true",會在回收連接時打印日志。removeAbandoned是連接池的高級功能,生產環境上應當慎重配置。

因為有時應用程序執行長事務,在這種情況下,極有可能連接會被連接池誤回收。

該配置一般在uat使用,為了定位連接泄漏的位置而去使用。生產環境中連接的關閉應該靠程序自己保證。

 

問題一產生原因:如上述所說,直接對號入座

 解決:1.適當增大 removeAbandonedTimeout時間,讓單次獲取的連接能夠執行時間更長一點,讓其支持更長一點的事務。

問題二產生原因:需要拐個彎,因為spring中配置事務時配置的service開啟一個事務,在service中拿到連接開啟一個事務,而遍歷中一直使用注入的dao去調用方法,

        其本質就是一直使用一個連接,不會遍歷一次執行完重新獲取連接,導致該連接超時被tomcat關閉回收。

 

解決2:將所有dao層方法抽出來另放一個業務service層,注入dao層,方法里使用dao的調用方法。在原來的service層中注入業務service,原有dao調用的方法,全部替換成業務service調用的方法。

    這樣每次業務service調用到(update、insert、delete)方法,就開啟一個事務,執行完就回收。再執行就有獲取一個連接,執行到事務方法后,又會主動關閉,

    就不會因連接超時被tomcat強行回收了!


免責聲明!

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



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