【问题标题】:Mysql Exception in JAVA projectJAVA项目中的Mysql异常
【发布时间】:2014-07-27 07:32:37
【问题描述】:

在一个只有 jdbc 和 mysql 的简单 java 应用程序中,我得到了错误:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection,  message from server: "Too many connections"

线程用于打开和关闭与 Mysql 的连接

我尝试增加 MySQL 的 max_connection 变量,但它只会延迟异常,因为如果增加线程数,它会再次出现

请提供根本原因和解决方案。

import java.sql.DriverManager;
import java.sql.SQLException;
public class Connection1 extends Thread{
public java.sql.Connection con = null;

public Connection1() throws ClassNotFoundException, SQLException {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        for(int i=0;i<500;i++) {
            new Thread(new Connection1().new  StartTester(i)).start();
        }
    }

    public void looper() throws ClassNotFoundException, SQLException {
        for(int i=0;i<2;i++) {
            new Thread(this.new  StartTester(i)).start();
        }
    }

    public void connect() throws ClassNotFoundException, SQLException {

        Class.forName("com.mysql.jdbc.Driver");
        con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","esignal");
        System.out.println("con success "+con);
        con.close();
        System.out.println("con Closed "+con);
    }

    class StartTester implements Runnable {

        public StartTester(int count) {
            System.out.println("Thread count "+count);
        }

        @Override
        public void run() {
            try {
                connect();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

【问题讨论】:

  • 在问题中加入一些代码可能会解决问题
  • 尝试使用一些数据库池,例如apache dbcp
  • 发布代码sn-p。
  • 看看this页面。
  • 请看下面的代码:

标签: java mysql exception


【解决方案1】:

请检查以下内容:-

  1. 检查数据库中打开的连接。
  2. 检查您的应用程序是否打开了太多连接而不是关闭它们。

【讨论】:

  • 所有连接打开后正常关闭
【解决方案2】:

尝试在打开和关闭连接的方法中添加“同步”关键字

【讨论】:

  • 不能使用同步,因为它肯定会解决问题,但会影响生产环境中的性能
【解决方案3】:

就像 Dennis 所说,您应该检查您的应用程序是否继续打开连接。 如果不是这种情况,那么您应该检查您的数据库可以处理多少个连接(查看您的数据库配置)。

我现在不知道在您运行应用程序之前建立了多少连接。您的数据库是高效的还是您有一个在本地运行的私有数据库?

如果有其他应用程序或用户使用您的数据库,则与您的数据库的连接可能已达到最大值或您的 RAM 不足。如果您没有足够的 RAM,mysql 可能不会打开更多连接。

【讨论】:

  • max_connections = 100
  • Mysql在本地运行
  • RAM 为 8 GB,因此打开连接不是问题
  • 就像你写的那样,你打开了 500 个打开连接的线程
  • 我尝试增加 max_connections 值,但它只会延迟异常,因为一旦线程超过限制它会再次发生
【解决方案4】:

您产生了太多Threads (500) 并且MySQL 上可用的连接数量有限(比如 20 个)。当您尝试创建数据库连接时,需要一些时间。但是线程会很快启动。所以几乎所有线程都在尝试同时连接到 DB,但只有 20 个(或多于 20 个)会获得连接,并且 reset 会抛出您提到的 Exception

  • 您应该使用 connectionPool 来正确管理连接。
  • 否则看看下面的link。它会告诉你如何正确处理Connections

我还建议您使用ExecutionService 来限制线程数,这是一种更简洁的方法(这就是我所做的)。您应该只使用创建 20 个活动(或任何最大连接数)线程并在准备运行模式下重置。因此推荐ExecutionService(最容易使用)。

我的示例解决方案将是(您需要正确实施connect() 方法,例如this

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Connection1 extends Thread {

    public static void main(String[] args) throws ClassNotFoundException,
    SQLException {
        // Number of max DB connection allowed
        int poolSize = 20;

        ExecutorService execService = Executors.newFixedThreadPool(poolSize);
        List<Future<String>> futureList = new ArrayList<Future<String>>();

        for (int i = 0; i < 500; i++) {
            System.out.println("Thread count " + i);
            Callable<String> worker = new StartTester();
            Future<String> future = execService.submit(worker);
            futureList.add(future);
        }
    }
}

class StartTester implements Callable<String> {
    @Override
    public String call() {
        try {
            connect();
            return "SUCCESS";
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return "FAILURE";
    }

    public void connect() throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test",
                "root", "esignal");
        System.out.println("con success " + con);
        con.close();
        System.out.println("con Closed " + con);
    }
}

【讨论】:

  • 你能详细说明一下吗?
  • 由于无法正确使用 ExecutionService,我该如何解决这个问题
  • 通过限制线程我可以解决这个独立的应用程序
  • 但是我该怎么办如果这是由处理线程生成的 TOMCAT 服务器处理的,即使在将线程关闭一个多小时后,这个异常仍然存在
  • 为此您需要配置存在于TOMCAT 目录中的context.xml 文件。在此文件中,您可以指定与连接池相关的所有属性以及ConnectionPool 驱动程序。我正在使用tomcat-jdbc 和类似于我提供的实现。现在 6 个月内运行良好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2012-08-07
  • 1970-01-01
  • 2012-03-10
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
相关资源
最近更新 更多