簡體   English   中英

從Tomcat中的池中止/清理無效的數據庫連接

[英]Aborting/cleaning up an invalid database connecton from pool in Tomcat

數據庫中斷后,Tomcat中的連接池出現問題。

有一個心跳服務servlet,在數據庫中斷后不會恢復。

我已經嘗試過標准答案 ,以及更進一步的方法:

  1. 在server.xml中添加到Resource部分

     validationQuery="select 1 from dual" testOnBorrow="true" removeAbandoned="true" removeAbandonedTimeout="120" logAbandoned="true" 
  2. 嘗試通過檢查有效性來關閉連接:

     if (connection != null && !connection.isValid(10)) { connection.close(); } 

    (導致java.sql.SQLException: Connection is closed

  3. 嘗試abort連接(不確定是否正確)

     if (connection != null && !connection.isValid(10)) { connection.abort(); } 

    (導致java.lang.NoSuchMethodError: java.sql.Connection.abort(Ljava/util/concurrent/Executor;)V

嘗試2)和3)顯示確實該連接無效,並且知道該連接。 問題是-如何銷毀它?

Tomcat版本:7.0.29

借助“ testOnBorrow = true”設置,該池將為您破壞無效的連接(請注意,“放棄”設置僅適用於未返回到池中的連接)。 所以這應該是這樣的:

  • servlet借用連接,查詢並返回到池的連接。
  • servlet借用連接,數據庫崩潰,servlet收到各種可怕的SQL錯誤,但仍返回到pool的連接
  • 數據庫已重新啟動
  • 在下一個心跳中,servlet借用連接。 Tomcat的池將“借用測試”,發現舊連接已斷開,刪除(並關閉)連接,嘗試另一個連接,發現它也已斷開,依此類推,然后該池決定創建一個新連接,對其進行測試,確定並將其交給servlet。
  • servlet接收新的有效連接,執行查詢並將連接返回到池。

我不確定當“借用測試”表明連接斷開時Tomcat的池的行為(1):當無法從池中獲得有效的連接時,它可能不會立即創建新的連接或拋出錯誤。 但我希望該池能夠有效刷新自身,並使用新的(有效)連接重新填充。

(1)也就是說,如果實際執行了“借用測試”,而該職位表明情況並非如此...


如果池本身不刷新,一旦發現連接無效,您可以嘗試以編程方式執行此操作。 我以前沒有嘗試過,希望您可以使用它。 下面介紹以下方法:
進入JNDI上下文,拉出DataSource對象,用手指交叉,將其投射到org.apache.tomcat.jdbc.pool。 DataSource ,然后調用purge()方法。
或者,使用JMX並通過MBean調用清除方法。

如果在數據庫崩潰后遇到掛起線程的情況,則可能必須求助於答案中描述的解決方法。

如果我們要從Tomcat jdbc連接池中處理一個錯誤的java.sql.connection,

我們可以在程序中明確地執行此操作。 將其解包到org.apache.tomcat.jdbc.pool.PooledConnection, setDiscarded(true)並最終關閉JDBC連接, ConnectionPool將在返回基礎連接后將其刪除。

(ConnectionPool.returnConnection(....))
                    PooledConnection pconn = conn.unwrap(PooledConnection.class);
                    pconn.setDiscarded(true);
                    conn.close();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM