同样的老故事:Tomcat DBCP + MySQL,MySQLNonTransientConnectionException:连接关闭后不允许任何操作
我在这里讨论了关于这个主题的相关问题,并且还搜索了一段时间。 似乎我仍然不明白Tomcat的DBCP配置或机制中的某些内容。
我得到了Tomcat 6,在server.xml
配置了DBCP资源:
我也找了mysql的wait_timeout
,默认是28800
。
总之,我尝试了几个选项,但似乎问题是mysql连接空闲28800秒,服务器关闭它们。 我认为池应该用validationQuery
和testOnBorrow
以某种方式处理这种情况,但似乎我错了。
如果我在空闲时段后在url
使用autoReconnect
我的第一次查询尝试导致“ ...CommunicationsException: The last packet successfully received from the server was 157,493,261 milliseconds ago.
”但在此之后它正常工作。
如果我在url
使用autoReconnectForPools
或者只是不使用它 – 在空闲时段(8小时)之后我每次.MySQLNonTransientConnectionException: No operations allowed after connection closed
得到“ .MySQLNonTransientConnectionException: No operations allowed after connection closed
”。
在这两种情况下,当应用程序加载时,情况会顺利 所以,我得出结论,连接是从mysql的一侧关闭的。
帮助,我错过了什么? 我想在不改变Mysql中的wait_timeout的情况下解决这个问题。 目标 – 稳定的应用程序,如果它发生可以在空闲时间生存:)
不确定它是否会有所帮助,但Tomcat 7.x中有一个更新的(据称更好的)连接池实现 – 要使用它,请将其添加到您的配置中:
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
我很确定所有其他选项都是一样的。 请参阅http://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.html
我想了一下,并决定留下这个问题,尽管问题根本不在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服务器终止过期连接时,我的应用程序会在第一次查询时获得有关超时的exception,但由于后续查询的autoReconnect,连接将再次存在。 游泳池刚刚没有触及连接,因为它从未被发布过。
最后我意识到了这一点,并通过将getMyResource
更改为:
private MyResource getMyResource() { return new MyResource(getConnection()); }
在我看来这是合理的。 在这一改变之后,所有事情都开始按预期工作。