MySql wait_timeout問題解決辦法。

寫的是JSP應用。java

只要8小時內沒有訪問數據庫,應用再次經過jdbc訪問數據庫就會發生異常。本人用的是Mysql5.5不能經過在連接字符竄增長autoReconnect=true解決。只有Mysql 4.x才能經過這個辦法解決。mysql

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

而後我就想,能不能開一個線程,每隔8小時訪問一次Mysql數據庫。原理sql

下面開始試驗。數據庫

我將Mysql5.5的 wati_timeout設置爲10ide

set global wait_timeout=10

只要過10秒不訪問訪問應用,那麼就會報錯。還原了事故現場。測試

而後增長如下代碼,增長一個線程,每隔10秒訪問一次數據庫,那麼就不會報錯,並且頁面正常顯示。下面的Listener使用的是Servlet 3.0的寫法,低版本的請百度。this

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()方法以下:url

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便可。spa

相關文章
相關標籤/搜索