如何重置JDBC连接池

您所在的位置:网站首页 怎么清除ps数据 如何重置JDBC连接池

如何重置JDBC连接池

2023-03-10 11:57| 来源: 网络整理| 查看: 265

我有一个问题,当我通过tomcat Web应用程序的用户请求重置我的MySQL数据库后,我收到了tomcat异常。我试图将此分解为设置,问题和我的分析,以帮助任何尝试阅读此内容的人。如何重置JDBC连接池

设置

复位基本上由从Java代码中调用一个bash脚本的:

删除MySQL的root用户的密码在旧版本的数据库 加载 在其上运行一些脚本 恢复所有密码

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

问题

一旦数据库被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)

即使用户在注销和背部,我会看到这个异常。如果我刷新页面四次​​,页面会每次加载一些不同的异常(上述所有变体 - 由于“EOFException:无法读取服务器响应”导致的CommunicationsException)。最后一次,一切似乎都正常运行。

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

分析

从我可以告诉,我认为这个问题与JDBC连接池做。我使用JNDI数据源如下访问我的数据库:

的server.xml:

的web.xml:

jdbc/mydb javax.sql.DataSource Container Shareable

的Java:

// 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我可以重新构造我的代码,这样如果在尝试查询时遇到异常,我可以重试该查询一次。如果它再次失败,那么我会知道真的有问题。如果通过,则连接成功重新建立。

问题在于代码中存在查询无处不在。对它们进行重新分解需要花费很多时间和测试,如果有必要,我会这样做,但是希望避免。另外,如果查询由于其他原因而失败,则在报告之前将尝试两次。对于长时间查询,这可能会导致严重的用户体验延迟,但只能在错误情况下进行。

另一种解决方案是强制重置/重新连接连接池中的所有连接。我可以以编程方式(即在调用bash脚本完成时从我的java代码)或bash脚本(例如使用某种类型的命令行实用程序)执行此操作。问题是,我不知道该怎么做,或者甚至有可能。

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

感谢大家的时间和帮助!

来源

2014-12-29 Trenin

+1

解决方案:不要删除您在数据库连接池中配置的用户的凭据。实际上,您不应该篡改mysql用户数据来改变数据库的状态。您应该只更改您正在使用的架构。 –

+0

@LuiggiMendoza谢谢。我曾想到这一点,但长话短说,这可能不是一种选择。运行的脚本没有修改数据库的凭据,所以我需要删除root用户的密码。另外,加载的新数据库可能有不同的密码。 – Trenin

+1

*我想到了这一点,但长话短说,这可能不是一个选项*然后在沉默u_u受苦。笑话,你不能*重置*数据库连接池。避免这样做,或者让有足够能力的用户来执行脚本。您可以创建另一个用户来执行此操作,或者关闭您的应用程序并重新启动它们并为此创建策略。 –



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3