c3p0遇到mysql的wait_timeout解决方法

来源:互联网 发布:最惨的男主 知乎 编辑:程序博客网 时间:2024/04/27 01:56

基础知识

c3p0:数据库连接池,可配置初始化数据库连接数等功能
wait_timeout:mysql的连接的配置 默认8小时 若此链接配置时间内无使用,则mysql会自动关闭

出现问题

1.当tomcat启动8小时后 当使用数据库链接时会抛出:数据链接已超时,建议提高wait_timeout配置的错误
2.某个轮询查询过段时间会出现缓存现象

解决问题步骤

1.网上搜索wait_timeout解决方法很多都是直接延长配置项,但这是治标不治本的方法,除非服务在配置项时间内定时重启,所以觉得此方法是实在解决不掉问题的后备实现方案:延长配置项时间+定时重启服务

mysql> set global wait_timeout=10;mysql> show global variables like 'wait_timeout';

2.重新review取数据库链接的java代码

     /**       *  将数据库连接绑在线程上 以保证用一个线程使用的都是同一个数据库连接           */      private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();        /**      * 获取数据库连接 同时将数据库连接绑定在线程上      * @return Connection      */     public static synchronized Connection getConnection(){             Connection conn = tl.get();             Date date = new Date();                   try {                                                             if(null == conn|| conn.isClosed()){                 conn = ds.getConnection();                   tl.set(conn);                                    }          } catch (SQLException e) {                   logger.error(e);;             }                        return conn;         }     

我底层取数据库链接的代码逻辑是:
一.将数据库链接绑在处理线程上,每次取数据库链接先从线程上看有没有绑定的或者有没有关闭链接 没有的话或者已关闭的话再去链接池里取数据库链接
二.理想环境的话,即使mysql配置项时间已到主动关链接的话,conn.isClosed()返回的应该也是true,但实际我将wait_timeout参数故意调小,让mysql主动关闭链接,但conn.isClosed()返回一直false,所以无法重新从链接池里取链接,而依旧使用线程上绑定的链接,而此链接已被mysql主动关闭,调用时就会报错(找到报错的原因)
3.解决方法
其实很简单每次使用完链接都close,原以为用了链接池,自己就不用主动close,关闭的任务交给链接池自己控制就行了,没想到还是得close,但这边close的时候数据库的链接实际并没有断,只是将链接交还会链接池而已。
可以通过查看数据库链接来判断是否真的关闭了

mysql> SHOW FULL PROCESSLIST;

缓存的问题一开始直接将所有数据库cache的配置全关了,发现没有用,后来将链接close后发现也解决了,我估计是原先没close的时候,轮询的处理可能不是同一个线程,当轮询到一个比较老的线程后,返回的就是缓存了

0 0
原创粉丝点击