MySql wait_timeout问题解决办法。

写的是JSP应用。

只要8小时内没有访问数据库,应用再次通过jdbc访问数据库就会发生异常。本人用的是Mysql5.5不能通过在链接字符窜增加autoReconnect=true解决。只有Mysql 4.x才能通过这个办法解决。

        private static String url = "jdbc:mysql://localhost:3306/remote?autoReconnect=true&useUnicode=true&characterEncoding=utf8";

然后我就想,能不能开一个线程,每隔8小时访问一次Mysql数据库。原理

下面开始试验。

我将Mysql5.5的 wati_timeout设置为10

set global wait_timeout=10

只要过10秒不访问访问应用,那么就会报错。还原了事故现场。

然后增加以下代码,增加一个线程,每隔10秒访问一次数据库,那么就不会报错,而且页面正常显示。下面的Listener使用的是Servlet 3.0的写法,低版本的请百度。

package servlet;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import utils.MysqlTool;


/**
 * 保持和MYSQL的链接,每8小时连接一次,Mysql wait_timeout为28800
 * @author 
 *
 */
@WebListener
public class KeepMysqlListener implements ServletContextListener {
    
    private MyThread myThread;  
    
    public KeepMysqlListener(){
        
    }
    
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        if (myThread != null && myThread.isInterrupted()) {  
               myThread.interrupt();  //销毁线程
           }  
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        if (myThread == null) {  
               myThread = new MyThread();  
               myThread.start(); // servlet 上下文初始化时启动线程
           }
    }
 

}

class MyThread extends Thread {  
public void run() {  
    while (!this.isInterrupted()) {// 线程未中断执行循环
                try {
                    MysqlTool.keepMysql();
                   Thread.sleep(10*1000); //每隔10m秒执行一次 测试成功后可以改成8小时的 8*60*60*1000ms
               } catch (InterruptedException e) {  
                   e.printStackTrace();  
               }  
           }  
       }  
}  

其中MysqlTool.keepMysql()方法如下:

package utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class MysqlTool {
        //数据库连接对象
        private static Connection conn = null;
         
        //驱动程序名
        private static String driver = "com.mysql.jdbc.Driver";
        //URL指向要访问的数据库名mydata
        private static String url = "jdbc:mysql://localhost:3306/remote?autoReconnect=true&useUnicode=true&characterEncoding=utf8";
        //MySQL配置时的用户名
        private static  String username = "root";
        //MySQL配置时的密码
        private static String password = "";
         
         
        // 获得连接对象
        private static synchronized Connection getConn(){
            if(conn == null){
                try {
                    Class.forName(driver);
                    conn = DriverManager.getConnection(url, username, password);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            return conn;
        }
      public static String keepMysql(){
            PreparedStatement pstmt = null;
            String sql = "SELECT 1 FROM USERS";
            ResultSet rs = null;
            String str= "";
            try {
                pstmt = getConn().prepareStatement(sql);
                rs = pstmt.executeQuery();
                //System.out.println(pstmt.toString());
                while (rs.next()) {
                   str = rs.getString(1);
                }
                rs.close();
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return str;
        }
}

测试成功之后,将代码中的10*1000替换成 8*60*60*1000即可。

原文地址:https://www.cnblogs.com/CryOnMyShoulder/p/10550711.html