返回JDBC连接池的死连接 - Glassfish 3.1.2.2

时间:2014-06-24 18:05:13

标签: java java-ee glassfish connection-pooling

发送死数据库连接时遇到{{3}}连接池问题。我使用jconn3(com.sybase.jdbc3)运行Glassfish 3.1.2.2以连接到Sybase 12.5。我们的组织每晚都会重新启动Sybase服务器。当在重新启动期间尝试使用数据库连接时,我的问题就会出现。以下是产生我的问题的操作顺序:

  • Sybase已关闭以重新启动。
  • 请求从池中连接。
  • 数据库操作按预期失败。
  • 连接以关闭状态返回到池中。
  • Sybase已备份。
  • 请求从池中连接。
  • 由于“连接已关闭”异常,数据库操作失败。
  • 连接将返回到池
  • 我已经实现了一个尝试从这种情况中恢复的数据库恢复单例。每当发生数据库异常时,我都会进行jmx调用以暂停所有队列并在JDBC连接池上执行flushConnectionPool操作。如果数据库连接仍未启动,则进程会设置计时器以在10分钟内重试。虽然这个过程有效,但并非没有缺陷。

    我意识到池上有一个设置,所以你可以在发送之前要求对数据库连接进行验证,但出于性能原因,我已经避开了这个设置。我的流程每天执行大约500万次数据库事务。

    我的问题是,有没有人知道如何避免首先将死连接返回池中?

    1 个答案:

    答案 0 :(得分:1)

    你已经很好地总结了你的选择。我们遇到了这个问题,午夜数据库崩溃了。对我们来说,我们启用了连接验证,但我们没有您的交易量。

    Glassfish提供了一个自定义验证选项,可以使用该选项指定一个类来进行验证。

    默认情况下,Glassfish提供的所有类(您将在控制台中看到它们作为选项提供)是这样的SQL语句:

    SELECT 1;
    

    语法在数据库之间有所不同,SQL Server使用'1',而对于Postgres,它只使用1.但意图是相同的。

    网络是每次尝试连接时都会花费额外的数据库命中率,但这真的非常便宜。但是,它仍然很受欢迎。

    但你可以实现自己的版本。它可以检查,例如,每10个请求,甚至更少的频率。将随机数从1滚动到N(N = 10,20,100 ......),如果得到'1',则执行选择(如果失败则失败),否则返回“true”。但同时,配置它以便在检测到错误时清除整个池。清楚地调整一下,这样当你的数据库在晚上瘫痪时(不管你的系统在晚上有多忙)与峰值处理相比,你很有可能发生这种情况。

    你甚至可以在高峰处理期间“降低赔率”。 “如果时间在早上6点到下午6点之间,那么赔率= 1000,否则赔率= 100;如果(随机(赔率)== 1){选择......}”

    随机选项消除了维护线程安全计数器的需要。

    最后,它并不重要,您只需要及时注意数据库已关闭,这样您就可以要求GF中止该池。

    我可以肯定地看到它在一开始就有点吵架,因为数据库出现了,可能不止一次刷新池,但这应该是无害的。

    你可以采用不同的方式,但这是一个需要考虑的途径。