寫的是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