前面的文章中,我介绍了修改mysql默认超时时间和配置proxool连接池的方法来解决Mysql超时重连的问题。方案1不推荐,它并没有从根本上解决问题;方案2可用,但配置相对复杂;所有才有了方案3,它既解决了关键问题,并且配置简单易懂。

c3p0连接池的testConnectionOnCheckout属性,类似于autoReconnect属性可自动保持数据库的连接,在获取连接时先检查连接是否有效(即检查Connection是否被mysql数据库关闭了),如果连接无效就重新建立一个新的连接。

C3P0连接池配置如下:

1、下载相关JAR包;

在Maven Repository中下载c3p0相关jar包,将c3p0-0.9.2.1.jar 拷贝至项目中。

2、在hibernate配置文件中,添加c3p0连接池配置,配置如下:

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE hibernate-configuration PUBLIC  
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
<hibernate-configuration>  
  
    <session-factory>
	<!-- 数据库方言 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- 数据库JDBC驱动类名 -->
	<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>		
        <!-- 数据库连接用户名 -->
	<property name="hibernate.connection.username">root</property>
	<!-- 数据库连接密码 -->
        <property name="hibernate.connection.password">123456</property>
	<!-- 数据库连接地址 -->
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/testDB</property>
        <!-- ddl语句自动建表 -->  
	<property name="hibernate.hbm2ddl.auto">update</property>
	<!-- 输出所有SQL语句到控制台 -->
	<property name="show_sql">false</property>
	<!-- 为"当前"Session指定一个(自定义的)策略 -->
        <property name="current_session_context_class">thread</property>
	<property name="hibernate.session.events.log">false</property>
		
	<!-- c3p0连接池配置 -->
        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
        <!-- 最大连接数。Hibernate默认为100 -->
	<property name="hibernate.c3p0.max_size">20</property>
        <!-- 最小连接数。Hibernate默认为1 -->
	<property name="hibernate.c3p0.min_size">5</property>
	<!-- 连接超时时间(单位为秒),超过此时间就从连接池中移除一个空闲的连接。Hibernate默认为0,永不过期 -->
	<property name="hibernate.c3p0.timeout">50000</property>
	<!-- 被缓存的预编译语句数量。Hibernate默认为0,缓存不可用-->  
        <property name="hibernate.c3p0.max_statements">100</property>
	<!-- 一个连接被自动验证前的闲置时间(单位为秒)。Hibernate默认为0 -->  
        <property name="hibernate.c3p0.idle_test_period">3000</property>
        <!-- 当连接池耗尽并接收到新的连接请求时,新增连接的数量 -->
        <property name="hibernate.c3p0.acquire_increment">2</property>
        <!-- 当连接释放时,校验连接的有效性 -->
	<property name="hibernate.c3p0.testConnectionOnCheckout">true</property>  
      
        <!-- 注册ORM映射文件 -->  
        <mapping class="com....." />  
      
    </session-factory>  
</hibernate-configuration>

上面配置中最重要的就是hibernate.c3p0.testConnectionOnCheckout这个属性,它保证每次取出连接时都会检查该连接是否被关闭,如果被关闭,则重新建立连接。

简单两步就搞定了mysql超时自动重连的问题了。

3、测试验证

①修改mysql默认超时time,超时参数设置的比较小(设置为2min)

SET GLOBAL wait_timeout=120;
SET GLOBAL interactive_timeout=120;

SHOW GLOBAL VARIABLES LIKE '%timeout%';

②启动web工程,登录系统,然后等待2分钟以上,再次操作系统检查是否会报mysql连接错误

经过验证,发现c3p0连接池配置能有效解决mysql超时重连问题。