模拟Jdbc在高并发的情况下出现如下异常的情况:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
代码如下:
public class JdbcTest {
private static String url = "jdbc:mysql://${数据库链接地址:端口号}/${数据库}";
private static String userName = "数据库名称";
private static String passWorld = "密码";
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
Connection connection = null;
public static Connection getConnection() throws Exception {
return DriverManager.getConnection(url, userName, passWorld);
}
}
public class JdbcTest100 {
static Connection connection;
//模拟200个线程同时获取数据库连接
private static int count = 200;
private static CountDownLatch countDownLatch = new CountDownLatch(count);
public static void main(String[] args) {
for (int i = 0; i < count; i++) {
new Thread(() -> {
try {
//阻塞,等待全部线程同时启动
countDownLatch.await();
String sql = "select 1 from dual";
connection = JdbcTest.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql);
boolean resultSet = preparedStatement.execute();
System.out.println(Thread.currentThread().getName() + "\t" + resultSet);
} catch (SQLException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}, String.valueOf(i)).start();
countDownLatch.countDown();
}
}
}
运行这个main方法后,有一定几率会报第一行的异常,导致这个异常的原因就是在并发的情况下,如果同时获取数据库的连接,系统资源有限,并且在大量的资源被占用后,得不到释放,就会导致问题,那么如何更好得解决这个问题呢,可以使用数据库连接池技术,这样做的好处就是不用频繁的new对象,然后导致大量的垃圾回收,没有达到资源重复利用的效果,使用数据库连接池就可以很好的避免这一点,使得资源重复被利用,下面一片文章将介绍手写一个数据库连接池。
有说不对的地方,欢迎大神留言指出来,相互学习,共同进步