0

我在这里检查了有关此主题的相关问题,并在 Google 上搜索了一段时间。似乎我仍然不理解 Tomcat 的 DBCP 配置或机制中的某些东西。

我在以下位置配置了 Tomcat 6、DBCP 资源server.xml

<Resource name="jdbc/myDB" auth="Container" description="Database connection"
  type="javax.sql.DataSource"
  driverClassName="com.mysql.jdbc.Driver"
  url="jdbc:mysql://myhost:3306/mydb?autoReconnectForPools=true&useUnicode=true"
  username="user"
  password="password"
  validationQuery="SELECT 1"
  testOnBorrow="true"
  testWhileIdle="true"
  timeBetweenEvictionRunsMillis="10000" minEvictableIdleTimeMillis="60000"
  maxActive="20" maxWait="20000" maxIdle="10"
  removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true" />

我也找了mysql wait_timeout,它是默认的28800

总之,我尝试了几个选项,但似乎问题是 mysql 连接达到了 28800 秒的空闲时间并且服务器关闭了它们。我认为该池应该以某种方式使用 and 来处理这种情况validationQuerytestOnBorrow但似乎我错了。

如果我autoReconnecturl空闲期后使用我的第一次查询尝试导致“ ...CommunicationsException: The last packet successfully received from the server was 157,493,261 milliseconds ago.”但在此之后它工作正常。

如果我使用或不使用它 - 在空闲期(8 小时)之后,我每次都得到“ autoReconnectForPools” 。url.MySQLNonTransientConnectionException: No operations allowed after connection closed

在这两种情况下,当应用程序加载时,事情都会顺利进行。因此,我得出结论,连接是从 mysql 一侧关闭的。

帮助,我错过了什么?我想在不更改 Mysql 中的 wait_timeout 的情况下解决这个问题。目标 - 稳定的应用程序,如果发生空闲时间,它可能会存活 :)

4

2 回答 2

0

不确定它是否会有所帮助,但在 Tomcat 7.x 中有一个更新(据说更好)的连接池实现 - 要使用它,请将其添加到您的配置中:

factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

我很确定所有其他选项都是相同的。见http://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.html

于 2013-01-24T12:02:02.737 回答
0

我想了想,决定留下这个问题,尽管问题根本不在 Tomcat DBCP 中。我之所以做出决定,是因为我发现了很多类似的问题,其中许多问题没有答案,也从未找到可能发生的事情的线索。所以,我在这里留言,作为对突然走上同一条道路的任何人的警告:

问题是我有一个使用数据库的资源,它只初始化了一次,比如:

class MyClass {
   private MyResource res = null;

   private MyResource getMyResource() {
      if (res == null) res = new MyResource(getConnection());
      return res;
   }

   private Connection getConnection() {
      ....
      con = dataSource.getConnection();
      ....
      return con;
   }
}

当我的应用程序在 Servlet 中时,它导致 MyResource 实例是唯一的实例,并且连接打开。因此,当 MySQL 服务器终止过期连接时,我的应用程序将在第一次查询时收到超时异常,但由于后续查询的自动重新连接,连接将再次处于活动状态。池只是没有触及连接,因为它从未被释放。

最后我意识到了这一点,并通过更改getMyResource为:

private MyResource getMyResource() {
  return new MyResource(getConnection());
}

就我而言,这是合理的。在此更改之后,所有事情都开始按预期工作。

于 2013-02-04T11:22:02.183 回答