在日常开发中,经常会涉及到数据库读写访问,对数据库访问通常会通过数据库连接池来获取数据库连接,再进行SQL,最近涉及到迁移数据,在日志中偶尔出现一些MySQL数据库连接错误,通过DB配置和连接池配置最终解决。
服务器日志中的错误信息大致如:
这样的错误重启应用后,便能暂时解决,但过不了多久又会出现,而且这个错误有可能一直持续下去。最终发现与MySQL超时连接配置有关。
wait_timeout和interactive_timeout需要同时设置才会生效。当数据库连接超过wait_timeout这段时间内,没有任何数据库操作,MySQL将主动关闭服务端连接,因此客户端再次进行数据库操作时,会报该错误,所以将这两个值设置得比较大,但其实设置过大,对安全和资源也有一定的损失。
所以最好开启c3p0连接池的自动检测功能,这样即便之前的连接被MySQL关闭了,也不容易出现上述的错误,除非连接池还没来得及检测连接是否可用,就被应用拿来使用了,但c3p0提供了同步检测连接的方式pool.setTestConnectionOnCheckout(true);,但这对应用性能是有所损失的。
上面的错误在数据库重启的时候也有可能报错,并且错误日志中会多出一部分MySQL关闭的信息:
但这种情况下,即便不启用c3p0的连接检测机制,只要应用的数据库操作间隔时间未超过MySQL配置的wait_timeout,下一次数据库操作仍能连接上。
c3p0从0.9.5以上开始支持JDBC 4的Connection.isValid(),所以可以不用设置检测语句pool.setPreferredTestQuery("SELECT 1")。