2014-12-06 40 views
0

我有全天候運行MySQL服務器和大量的SWT富客戶端訪問使用JPA/Hibernate的數據庫...的Java /休眠的客戶端重新連接

如果客戶端計算機(筆記本電腦)去冬眠/待機,並在一段時間後喚醒數據庫連接丟失 - 無論是什麼樣的設置和/或數據庫連接提供商(我試過c3p0和振動)我使用....

這是我目前的休眠。 xml屬性文件(這也不起作用)...:

<property name="connection.pool_size">3</property> 
    <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> 
    <property name="hibernate.cache.use_query_cache">false</property> 

    <property name="hibernate.current_session_context_class">thread</property> 

    <property name="hibernate.c3p0.validate">true</property> 
    <property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property> 
    <property name="hibernate.c3p0.min_size">5</property> 
    <property name="hibernate.c3p0.max_size">600</property> 
    <property name="hibernate.c3p0.timeout">0</property> 
    <property name="hibernate.c3p0.max_statements">50</property> 
    <property name="hibernate.c3p0.preferredTestQuery">SELECT 1;</property> 
    <property name="hibernate.c3p0.testConnectionOnCheckout">true</property> 
    <property name="hibernate.c3p0.testConnectionOnCheckin">true</property> 
      <property name="hibernate.c3p0.idle_test_period">3000</property> 
    <property name="hibernate.c3p0.acquireRetryAttempts">10</property> 
    <property name="hibernate.c3p0.acquireRetryDelay">1000</property> 
    <property name="hibernate.c3p0.breakAfterAcquireFailure">false</property> 

這裏是一個錯誤堆棧跟蹤:

WARN | 02.12.2014 21:35:06,503 | [C3P0PooledConnectionPoolManager[identityToken->1hge13a96372xk9xvyjyj|1dd3180]-AdminTaskTimer] | ThreadPoolAsynchronousRunner:743 | com[email protected]89789 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
WARN | 02.12.2014 21:35:06,507 | [C3P0PooledConnectionPoolManager[identityToken->1hge13a96372xk9xvyjyj|1dd3180]-AdminTaskTimer] | ThreadPoolAsynchronousRunner:759 | com[email protected]89789 -- APPARENT DEADLOCK!!! Complete Status: 
    Managed Threads: 3 
    Active Threads: 3 
    Active Tasks: 
     com[email protected]b76a87 
      on thread: C3P0PooledConnectionPoolManager[identityToken->1hge13a96372xk9xvyjyj|1dd3180]-HelperThread-#0 
     com[email protected]1b2ffe7 
      on thread: C3P0PooledConnectionPoolManager[identityToken->1hge13a96372xk9xvyjyj|1dd3180]-HelperThread-#1 
     com[email protected]becbe1 
      on thread: C3P0PooledConnectionPoolManager[identityToken->1hge13a96372xk9xvyjyj|1dd3180]-HelperThread-#2 
    Pending Tasks: 
     com[email protected]3b2d78 
Pool thread stack traces: 
    Thread[C3P0PooledConnectionPoolManager[identityToken->1hge13a96372xk9xvyjyj|1dd3180]-HelperThread-#0,5,main] 
     java.net.DualStackPlainSocketImpl.connect0(Native Method) 
     java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79) 
     java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) 
     java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) 
     java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) 
     java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) 
     java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) 
     java.net.Socket.connect(Socket.java:579) 
     java.net.Socket.connect(Socket.java:528) 
     java.net.Socket.<init>(Socket.java:425) 
     java.net.Socket.<init>(Socket.java:241) 
     com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:259) 
     com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:307) 
     com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2482) 
     com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2519) 
     com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2304) 
     com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:834) 
     com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) 
     sun.reflect.GeneratedConstructorAccessor249.newInstance(Unknown Source) 
     sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
     java.lang.reflect.Constructor.newInstance(Constructor.java:526) 
     com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 
     com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:416) 
     com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:346) 
     com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:146) 
     com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:195) 
     com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:184) 
     com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:200) 
     com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1086) 
     com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1073) 
     com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:44) 
     com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1810) 
     com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:648) 
    Thread[C3P0PooledConnectionPoolManager[identityToken->1hge13a96372xk9xvyjyj|1dd3180]-HelperThread-#2,5,main] 
     java.net.DualStackPlainSocketImpl.connect0(Native Method) 
     java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79) 
     java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) 
     java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) 
     java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) 
     java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) 
     java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) 
     java.net.Socket.connect(Socket.java:579) 
     java.net.Socket.connect(Socket.java:528) 
     java.net.Socket.<init>(Socket.java:425) 
     java.net.Socket.<init>(Socket.java:241) 
     com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:259) 
     com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:307) 
     com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2482) 
     com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2519) 
     com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2304) 
     com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:834) 
     com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) 
     sun.reflect.GeneratedConstructorAccessor249.newInstance(Unknown Source) 
     sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
     java.lang.reflect.Constructor.newInstance(Constructor.java:526) 
     com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 
     com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:416) 
     com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:346) 
     com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:146) 
     com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:195) 
     com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:184) 
     com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:200) 
     com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1086) 
     com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1073) 
     com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:44) 
     com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1810) 
     com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:648) 
    Thread[C3P0PooledConnectionPoolManager[identityToken->1hge13a96372xk9xvyjyj|1dd3180]-HelperThread-#1,5,main] 
     java.net.DualStackPlainSocketImpl.connect0(Native Method) 
     java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79) 
     java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) 
     java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) 
     java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) 
     java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) 
     java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) 
     java.net.Socket.connect(Socket.java:579) 
     java.net.Socket.connect(Socket.java:528) 
     java.net.Socket.<init>(Socket.java:425) 
     java.net.Socket.<init>(Socket.java:241) 
     com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:259) 
     com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:307) 
     com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2482) 
     com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2519) 
     com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2304) 
     com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:834) 
     com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) 
     sun.reflect.GeneratedConstructorAccessor249.newInstance(Unknown Source) 
     sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
     java.lang.reflect.Constructor.newInstance(Constructor.java:526) 
     com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 
     com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:416) 
     com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:346) 
     com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:146) 
     com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:195) 
     com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:184) 
     com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:200) 
     com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1086) 
     com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1073) 
     com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:44) 
     com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1810) 
     com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:648) 


WARN | 03.12.2014 10:29:20,014 | [main] | SqlExceptionHelper:145 | SQL Error: 0, SQLState: 08S01 
ERROR | 03.12.2014 10:29:20,015 | [main] | SqlExceptionHelper:147 | The last packet successfully received from the server was 65.896.659 milliseconds ago. The last packet sent successfully to the server was 65.896.672 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. 

回答

0

線程是在獲取時,數據庫服務器(或筆記本電腦客戶端)下跌已經得到陷入新的數據庫連接的過程。他們正在與DBMS進行中間通信,並簡單地懸掛。他們既沒有成功獲得連接,也沒有及時通過例外失敗。這些掛起的線程正在使線程池飽和,從而阻止完成各種任務。一段時間後,c3p0聲明一個APPARENT DEADLOCK!,然後放棄並替換其線程池中的所有線程以重新開始。通常在APPARENT DEADLOCK後應用程序恢復並正常工作!但是,如果連接嘗試由於中斷而中斷,但不成功,也不會失敗,您可能偶爾會看到這些死鎖。

有些事情可能會有所幫助。如果連接採集嘗試卡住的I/O操作是可中斷的,則可以通過設置maxAdministrativeTaskTime來阻止APPARENT DEADLOCKS。但是如果I/O不可中斷,那是行不通的。

如果您經常看到這些死鎖,那可能意味着您正在通過Connections快速攪動。在一個調整良好的池中,連接獲取嘗試應該很少,因此發生中斷多次收購也應該是非常罕見的。在上面的配置中沒有任何東西會導致你通過Connections進行瀏覽,但是你說你引用的配置「不起作用」,所以也許真正的c3p0配置是不同的。 c3p0 DataSource在INFO級別上在池初始化時轉儲其配置。如果你搜索你的日誌,你可以驗證你打算的配置是否實際上是你的c3p0數據源的配置。

0

因爲它們都掛在連接上,請嘗試爲MySQL JDBC驅動程序(在MySQL connector J documentation中提到)設置connectTimeout。默認情況下,沒有超時可能導致它們永遠懸掛。

在客戶端應用程序中進行待機和喚醒是應該捕獲的,以便您可以採取措施防止出現錯誤(例如關閉數據庫連接並打開新的連接)。請參閱this answer,瞭解如何捕獲這些類型的事件,但不幸的是,答案不包括WM_POWERBROADCAST事件(在Windows上)的示例,該事件似乎發出待命/喚醒信號。我找到了一篇關於Windows的StandByDetector的文章(YMMV)。您可能想嘗試使用HikariCP數據庫連接池而不是c3p0(我懷疑HikariCP更擅長從損壞的數據庫連接中恢復)。您可以瀏覽設置演示HibHik以開始使用。