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