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即可。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM