写的是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即可。