java jdbc 连接池_java – 如何重置JDBC连接池

我有一个问题,我在用户通过tomcat web应用程序请求重置我的

MySQL数据库后得到了tomcat异常.到目前为止,我已尝试将其分解为设置,问题和分析,以帮助任何人尝试阅读此内容.

建立

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

>删除root mysql用户密码

>加载旧版本的数据库

>在其上运行一些脚本

>恢复所有密码

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

问题

一旦tomcat应用程序查询了DB,就会出现异常:

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中:

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中:

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脚本(例如使用某种类型的命令行实用程序)执行此操作.问题是,我不知道该怎么做,或者甚至可能.

我在Interceptor上找到了一些文档,但我不确定这是否适用于重置连接.我会继续调查.

感谢大家的时间和帮助!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值