druid連接池異常



在從excel導入10W條數據到mysql中時,運行一段時間就會拋這個異常,連接池問題

org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.TransactionException: JDBC begin failed:
Caused by: java.sql.SQLException: connection holder is null
	at com.alibaba.druid.pool.DruidPooledConnection.checkState(DruidPooledConnection.java:1085)
	at com.alibaba.druid.pool.DruidPooledConnection.getMetaData(DruidPooledConnection.java:825)
	at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:285)


找了下解決方案
1.

給jdbc url 增加 autoReconnect=true 一定能解決你的問題,可以定期觀察一下 show processlist
改進方法如下:
<property name="url" value="jdbc:mysql://localhost/數據庫實例名稱?&useUnicode=true&characterEncoding=utf-8&autoReconnect=true"/>

2.

尋找支持重連的連接池。
           注意:c3p0連接池支持重連;重連參數是:
               idleConnectionTestPeriod   設置空閑連接測試周期
               preferredTestQuery : 設置一查詢語句,用於重連測試
              testConnectionOnCheckin設置為true
              testConnectionOnCheckout設置為true

在sessionFactory里配置:

<property name="hibernateProperties">
   <props>

        <prop key="hibernate.autoReconnect">true</prop>

  </props>
</property>
這兩種不同的配置都是使連接池自動重連

后面發現問題還是存在

通過研究源碼我可以確定"Druid提供的getConnection()或者getConnection(long maxWaitMillis)方法不能保證在同一個線程中獲取的始終是一個連接,直到顯示的將連接關閉嗎?"。必須在程序在緩存從Druid中取出的連接才能保證現一個事務在使用的是同一個連接。

而拋出“connection holder is null”異常的原因可能在於:

關閉長時間不使用的連接超時時間,單位秒
removeAbandonedTimeout

假設這個參數的值 為30分鍾,當一個連接在獲取后30分鍾還沒釋放,也就是Connection的DruidPooledPreparedStatement對象執行完了executXXX()方法但還未執行close、commit、rollback方法,對應於Connection的running參數的值為false,這時Durid的DestroyConnectionThread線程會自動將該連接回收。當程序要commit()連接時會執行checkState()方法,這個方法會執行以下代碼:

if (holder == null) {  
 if (disableError != null) {  
   throw new SQLException("connection holder is null", disableError);  
    } else {  
   throw new SQLException("connection holder is null");  
    }  
} 



這段代碼就是我們看到的“connection holder is null”異常的來源,因此,我們需要做的就是根據Druid提供的監控信息(主要看“連接持有時間分布”的值)修改這個參數的值,它的值一定要比最長的連接持有時間還要大。

最后我把鏈接自動清除配置關閉解決了問題
removeAbandoned=false
如果把這個時間調整大一點應該也是可以的
removeAbandonedTimeout=1800


免責聲明!

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



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