写的是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的写法,低版本的请百度。
packageservlet;importjavax.servlet.ServletContextEvent;importjavax.servlet.ServletContextListener;importjavax.servlet.annotation.WebListener;importutils.MysqlTool;/*** 保持和MYSQL的链接,每8小时连接一次,Mysql wait_timeout为28800
*@author**/@WebListenerpublic class KeepMysqlListener implementsServletContextListener {privateMyThread myThread;publicKeepMysqlListener(){
}
@Overridepublic voidcontextDestroyed(ServletContextEvent arg0) {if (myThread != null &&myThread.isInterrupted()) {
myThread.interrupt(); //销毁线程
}
}
@Overridepublic voidcontextInitialized(ServletContextEvent arg0) {if (myThread == null) {
myThread= newMyThread();
myThread.start();//servlet 上下文初始化时启动线程
}
}
}class MyThread extendsThread {public voidrun() {while (!this.isInterrupted()) {//线程未中断执行循环
try{
MysqlTool.keepMysql();
Thread.sleep(10*1000); //每隔10m秒执行一次 测试成功后可以改成8小时的 8*60*60*1000ms
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
其中MysqlTool.keepMysql()方法如下:
packageutils;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.util.ArrayList;importjava.util.List;public classMysqlTool {//数据库连接对象
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 synchronizedConnection getConn(){if(conn == null){try{
Class.forName(driver);
conn=DriverManager.getConnection(url, username, password);
}catch(ClassNotFoundException e) {
e.printStackTrace();
}catch(SQLException e) {
e.printStackTrace();
}
}returnconn;
}public staticString 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();
}returnstr;
}
}
测试成功之后,将代码中的10*1000替换成 8*60*60*1000即可。