下方是一个开机自启动的ServerSocket服务 ,由于启动比MySQL数据库快,导致数据库连接池创建失败。因此增加了testJDBC()方法进行递归,直至连接成功。
package socket;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
//import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeUnit;
import org.apache.tomcat.jdbc.pool.DataSource;
/**
* 使用长连接2001端口(新项目20231228)
* @author Administrator
*
*/
public class M3_5 {
public static void main(String[] args) {
/* 不成功重连jdbc */
testJDBC();
// 配置数据源
DataSource dataSource = new DataSource();
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/plc?characterEncoding=UTF8");
dataSource.setUsername("root");
dataSource.setPassword("111111");
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
// dataSource.setTestOnBorrow(true);
// dataSource.setTestOnReturn(true);
dataSource.setValidationQuery("select 1 from dual");
dataSource.setValidationInterval(3600000);
dataSource.setTestWhileIdle(true);
dataSource.setTimeBetweenEvictionRunsMillis(3600000);
dataSource.setMinIdle(1);
dataSource.setInitialSize(1);
System.out.println(dataSource.getMinIdle());
System.out.println(dataSource.getMaxIdle());
System.out.println(dataSource.getMaxActive());
System.out.println(dataSource.getIdle());
System.out.println(dataSource.getActive());
try(ServerSocket s = new ServerSocket(2001)){
ExecutorService pool = Executors.newFixedThreadPool(4);
while(true) {
Socket socket = s.accept();
pool.execute(new Task(socket,dataSource));
ThreadPoolExecutor t = (ThreadPoolExecutor)pool;
System.out.println("active:"+t.getActiveCount());
System.out.println("core:"+t.getCorePoolSize());
System.out.println("TaskCount"+t.getTaskCount());
// System.out.println("CompletedTaskCount:"+t.getCompletedTaskCount());
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 不成功重连功能
*/
private static void testJDBC() {
// 数据库连接信息
String url = "jdbc:mysql://127.0.0.1:3306/plc?characterEncoding=UTF8";
String user = "root";
String password = "111111";
try {
// 加载数据库驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 建立连接
Connection connection = DriverManager.getConnection(url, user, password);
// 检查连接是否成功
if (connection != null && !connection.isClosed()) {
System.out.println("数据库连接成功!");
} else {
System.out.println("数据库连接失败!");
}
// 关闭连接
connection.close();
} catch (ClassNotFoundException e) {
System.out.println("数据库驱动未找到!");
} catch (SQLException e) {
System.out.println("数据库连接异常:" + e.getMessage());
try {
System.out.println("等待5秒后重试");
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
testJDBC();
} catch (Exception e) {
System.out.println("未知异常:" + e.getMessage());
}
}
}
核心在于,jdbc连接失败报SQLException异常,在该异常捕获后,延迟5秒重新调用testJDBC方法,如此递归,直至成功。