当前位置: 首页 > 知识库问答 >
问题:

如何重置JDBC连接池

颛孙霖
2023-03-14

我有一个问题,在通过tomcat web应用程序应用户请求重置MySQL数据库后,我会收到tomcat异常。到目前为止,我已尝试将其分解为设置、问题和我的分析,以帮助任何试图阅读本文的人。

重置基本上包括从java代码调用bash脚本以:

  • 删除根mysql用户密码
  • 加载数据库的旧版本
  • 在上面运行一些脚本
  • 恢复所有密码

这是一个用户启动的过程,通常将数据库恢复到以前的状态,但它也用于从另一个系统导入数据库。一旦一切完成,用户然后尝试访问Web应用的不同部分(即使用相同的会话而不注销/重新登录),该部分执行数据库查询以获取一些数据。

tomcat应用程序查询数据库后,会出现异常:

Dec 29, 2014 3:49:50 PM ERROR BasicSecurityRealm:216 - 
ERROR: ----- SQLException -----

Dec 29, 2014 3:49:50 PM  INFO BasicSecurityRealm:218 - Exceptioncom.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 234,810 milliseconds ago.  The last packet sent successfully to the server was 12 milliseconds ago.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
...
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2540)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2990)

即使用户注销并重新登录,我也会看到此异常。如果我刷新页面四次,页面每次都会加载多一点,但会出现一些不同的异常(上面的所有变体-由“EOFEException:Can not read response from server”引起的CommunicationsException)。最后一次,一切似乎都正常运行。

要避免这些异常,我唯一能做的就是重新启动tomcat。我希望避免这种情况,因为这将意味着当前登录的用户将丢失会话,并且必须等待tomcat重新启动才能重新登录。强迫他们注销/重新登录可能是一个可以接受的折衷方案,但这并不能解决问题。

据我所知,我认为问题与JDBC连接池有关。我使用JNDI数据源访问我的数据库,如下所示:

服务器xml:

  <GlobalNamingResources>
    <Resource name="jdbc/mydb"
              auth="Container"
              type="javax.sql.DataSource"
              maxActive="30" maxIdle="30" maxWait="2147483647"
              username="x" password="x"
              driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/mydb?autoReconnect=true"/>

web.xml:

<!-- Data source definitions -->
<resource-ref>
    <res-ref-name>jdbc/mydb</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

爪哇:

    // Get connection to specified database
    Context initCtx = new InitialContext();
    Context envCtx = (Context) initCtx.lookup("java:comp/env");
    DataSource ds = (DataSource) envCtx.lookup("jdbc/mydb");
    con = ds.getConnection();
    stmt = con.createStatement();
    rs = stmt.executeQuery("...");

我认为连接池包含过时/失效的连接。每当我与ds建立连接时。getConnection,则它将获得这些旧连接中的一个。第一次尝试使用它将失败,连接将被重置(请注意,我使用的是autoReconnect=true,因此第二次应该(并且确实)起作用)。但是,池中包含许多(在我的例子中,经验上是4或5个)陈旧的连接,因此需要一段时间才能正确重置它们。重置连接后,一切正常。

因为我使用了autoReconnect=true我可以重新构造我的代码,这样如果我在尝试查询时遇到异常,我就可以重试查询一次。如果它再次失败,那么我就会知道确实存在问题。如果通过,则连接已成功重新建立。

这样做的问题是代码中存在查询EVERYWHERE。重新分解它们需要大量的时间和测试,如果有必要,我会这样做,但希望避免。此外,如果查询因其他原因失败,则在报告之前将尝试两次。对于长查询,这可能会有显著的用户体验延迟,但仅在错误条件下。

另一个解决方案是强制重置/重新连接连接池中的所有连接。我可以通过编程方式(例如,当bash脚本调用完成时,通过我的java代码)或bash脚本(例如,通过某种类型的命令行实用程序)来实现这一点。问题是,我不知道如何做到这一点,或者这是否可能。

我找到了一些关于拦截器的文档,但我不确定这是否适用于重置连接。我会继续调查。

感谢大家的时间和帮助!

共有3个答案

公羊晟
2023-03-14

该异常将引发由于您的项目包含多个ojdbcjars(ojdbc6或ojdbc14)在那一刻你可能会得到异常,当你试图连接oracle12c删除所有ojdbcjars在您的项目和添加任何一个jar中,只推荐一个是ojdbc7jar。

汲时铭
2023-03-14

您可以在从池中获取之前测试连接。

添加连接池配置:

validationQuery=TEST SQL
testOnBorrow=true
张鹏鹍
2023-03-14

你可以在从游泳池出来之前测试连接

默认情况下Tomcat

在这两种情况下,将下一个属性添加到连接池配置中:

validationQuery=<TEST SQL>
testOnBorrow=true
 类似资料:
  • 是否可以配置WebLogic的JDBC连接池,以便在经过一定时间后重置已建立的连接,即使该连接处于活动状态?

  • 问题内容: 我有一个Runnable,它从如下所示的连接池中获得连接,并有60秒的时间对连接进行处理: 当线程在60s之后死掉时,我假定连接已返回到池中,并且当创建新线程时,可以重新使用该连接。但是当我列出我的网络连接时,随着创建更多线程,该列表会不断增长。如上创建的连接是否正确返回到池中,如果可以,我如何强制重新使用连接? 问题答案: 您实际上并没有使用连接池。A 不能直接使用。其目的是作为一个

  • 我在Spring JDBC中使用Spring Boot 1.5.4。 使用Spring JDBC的Spring Boot微服务在尝试执行HTTP PUT时(在一群用户尝试执行HTTP PUT后)会出现以下问题,该问题会逐渐进入Spring JDBC调用: pom.xml: 我猜我需要设置一个JDBC连接池... 在我的application.properties设置中,(我有两个不同的数据库——一

  • 我的Spring Hibernate Web应用程序在MySQL上运行,这给我带来了麻烦。 我四处寻找并尝试了不同的配置,在这个网站上阅读了相当多的帖子,但它仍然会弹出微笑的头像。 错误消息是:由:com.mysql.jdbc.exceptions.jdbc4.通信异常:从服务器成功接收到的最后一个数据包是63,313,144毫秒前。最后一个成功发送到服务器的数据包是63,313,144毫秒前。比

  • null 任何想法都将受到赞赏。