DB重置后重新连接HikariCP

时间:2017-12-21 09:03:48

标签: hikaricp

这类似于我在2年前发布的this问题。

我有一个简单的测试,可以从数据库中连续读取。我停止/启动我的SQL Server实例。

function insertTableRow ( p_iId, d_prijs, c_prijs, code, artikelNL )
{
    var $id = $('.buttonbewerken[data-id='+p_iId+']');
    var row = '<tr>';
    row += '<td class="d_prijs ruimte">5427.00</td>';
    row += '<td class="c_prijs ruimte">9999.99</td>';
    row += '<td class="code ruimte">45t45tdfgr</td>';
    row += '<td class="artikelnl ruimte">gdrge5t5</td>';
    row += '<td><button data-id= class="buttonbewerken">bewerken</button></td>';
    row += '</tr>';

    $('#result').prepend(row);
}

如果simpleRead()中发生错误,则会正确处理所有错误。如果在testConnectionReset()中发生错误,则在重新启动数据库时,我有以下stackTrace并且没有重新连接。

@Test
public void testConnectionReset() {
while (true) {
  try {
   simpleRead();
  }
  catch (Exception e) {
    e.printStackStrace();
  }
}

@com.google.inject.persist.Transactional
protected void simpleRead() {
  dao = new MyDao(....)
  dao.findBy(...)
}

我目前的解决方法是将[2017-Dec-21 10:47:26] - [ERROR] - I/O Error: Connection reset by peer: socket write error org.hibernate.TransactionException: Unable to rollback against JDBC Connection at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.rollback(AbstractLogicalConnectionImplementor.java:121) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.rollback(JdbcResourceLocalTransactionCoordinatorImpl.java:250) at org.hibernate.engine.transaction.internal.TransactionImpl.rollback(TransactionImpl.java:100) at com.google.inject.persist.jpa.JpaLocalTxnInterceptor.rollbackIfNecessary(JpaLocalTxnInterceptor.java:153) at com.google.inject.persist.jpa.JpaLocalTxnInterceptor.invoke(JpaLocalTxnInterceptor.java:74) at temp.testConnection(TestConnection.java:45) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84) at org.testng.internal.Invoker.invokeMethod(Invoker.java:714) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111) at org.testng.TestRunner.privateRun(TestRunner.java:767) at org.testng.TestRunner.run(TestRunner.java:617) at org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) at org.testng.SuiteRunner.run(SuiteRunner.java:240) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224) at org.testng.TestNG.runSuitesLocally(TestNG.java:1149) at org.testng.TestNG.run(TestNG.java:1057) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:132) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:236) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:81) Caused by: java.sql.SQLException: Connection is closed at com.zaxxer.hikari.pool.ProxyConnection$ClosedConnection.lambda$getClosedConnection$0(ProxyConnection.java:490) at com.sun.proxy.$Proxy84.rollback(Unknown Source) at com.zaxxer.hikari.pool.ProxyConnection.rollback(ProxyConnection.java:377) at com.zaxxer.hikari.pool.HikariProxyConnection.rollback(HikariProxyConnection.java) at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.rollback(AbstractLogicalConnectionImplementor.java:116) ... 29 more 设置为0,每次在池返回之前强制进行连接检查。我发现很难相信这是一个Hikari bug,因为我没有看到其他任何人遇到这个问题,所以也许我还缺少其他一些配置。

我的筹码是

  • 列表项
  • SQL Server
  • JTDS(1.3.1)驱动程序。 (我尝试过类似结果的SQL Server驱动程序)
  • HikariCP(2.7.4)
  • Google guice(4.1.0)
  • Hibernate(5.2.11)

1 个答案:

答案 0 :(得分:0)

这是guice-persist中的错误。它与this紧密相关。事件的简单流是这样的

  1. Hikari在池中具有有效的连接
  2. 与数据库的连接丢失
  3. Guice-prersist @Transactional被调用,并从池中拉出连接(未选中)。
  4. Guice执行txn.begin(),引发异常,但BUT未能结束unitOfWork / closeConnection。池仍处于不良状态。

我发现的解决方法是以下其中一种

  1. 手动处理unitOfWork。
  2. 通过将aliveBypassWindowMs设置为0,要求Hikari在每次从池返回连接时检查连接。
  3. 在必要时通过结束unitOfWork直接修改有问题的类(JpaLocalTxnInterceptor)。