msyql的连接被创建之后,如果没有手动关闭连接,mysql默认会在8小时之后回收连接

在应用程序中,可能会遇到如下的错误信息:


Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
 at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

No operations allowed after connection closed.是说连接已经失效(关闭),不能进行数据库的相关操作。
原因是因为:应用程序之后,为了复用数据库连接,提高连接的使用效率和应用程序的性能。会使用连接池,事先创建若干的连接放在这个连接池中,连接池中的连接,由连接池管理器统一管理,包括连接池连接的扩展,获取,回收等。

一般在使用数据库连接池的时候,可能对连接池的配置使用不是很了解,所以可能没有检测数据库连接的有效性,当你在使用连接池中的某个连接做某种操作的时候,到数据库服务器那边才发现,原来现在使用的这个连接已经close失效了(连接池并不知道),所以会导致No operations allowed after connection closed错误信息。

现在业内有很多连接池提供方如c3p0,dbcp,proxool等,每个连接池的配置信息也不一样,所以解决上述问题的方案也不一样,但是问题的原因找到之后,问题也就好解决,具体解决方案要看具体连接池的配置。

明白问题之后,解决这个问题也就有两个思路了。

  • 延长MySQL的wait_timeout

  • 让连接池主动去测试持有的链接是否有效

考虑到实际中的应用,第一种思路其实并不是很好,因为作为连接池,理所应当地管理一切跟链接有关的东西,所以,从第二种思路入手比较合适些。
关于链接失效的问题,

C3P0官方文档给出了这样子的解决方式:

Begin by setting testConnectionOnCheckout to true and get your application to run correctly and stably. If you are happy with your application’s performance, you can stop here! This is the simplest, most reliable form of Connection-testing, but it does have a client-visible performance cost.

If you’d like to improve performance by eliminating Connection testing from clients’ code path:

Set testConnectionOnCheckout to false

Set testConnectionOnCheckin to true

Set idleConnectionTestPeriod to 30, fire up you application and observe. This is a pretty robust setting, all Connections will tested on check-in and every 30 seconds thereafter while in the pool. Your application should experience broken or stale Connections only very rarely, and the pool should recover from a database shutdown and restart quickly. But there is some overhead associated with all that Connection testing.

简单点概括,在配置C3P0的时候,如果要防止链接失效的情况,可以配置一个testConnectionOnCheckout的属性,该属性会比较大的影响性能。

如果比较在意性能的,可以设置testConnectionOnCheckout为false,设置testConnectionOnCheckin为true,设置idleConnectionTestPeriod为30秒

spring中配置数据源(其他架构改相应的配置属性即可)

相关配置.png

这里以c3p0为列,其他的数据源的结局思路一样,不重述。

文章来源于互联网:mysql数据库连接失效问题

发表评论