【问题标题】:Java MySQL connetion pool is not workingJava MySQL 连接池不工作
【发布时间】:2013-08-07 12:49:35
【问题描述】:

我用 Java 编写了一个运行 MySQL 查询并返回结果的函数。我在这里使用这种方法实现了连接池:http://www.kodejava.org/how-do-i-create-a-database-connection-pool/。该功能正在运行,但连接时间仍然与没有池的情况相同约 190 毫秒。谁能告诉我我做错了什么?

这是我的代码:

public static ArrayList<Map<String,Object>> query(String q) throws Exception {

    long start, end;

    GenericObjectPool connectionPool = null;

    String DRIVER = "com.mysql.jdbc.Driver"; 
    String URL = "jdbc:mysql://localhost/dbname";
    String USER = "root";
    String PASS = "";

    Class.forName(DRIVER).newInstance();

    connectionPool = new GenericObjectPool();
    connectionPool.setMaxActive(10);

    ConnectionFactory cf = new DriverManagerConnectionFactory(URL, USER, PASS);

    PoolableConnectionFactory pcf = new PoolableConnectionFactory(cf, connectionPool, null, null, false, true);

    DataSource ds = new PoolingDataSource(connectionPool);

    //create statement
    Statement Stm = null;

    try {

        Connection Con = null;
        PreparedStatement stmt = null;

        start = System.currentTimeMillis();

        Con = ds.getConnection();

        end = System.currentTimeMillis();
        System.out.println("DB Connection: " + Long.toString(end - start) + " ms");

        //fetch out rows
        ArrayList<Map<String, Object>> Rows = new ArrayList<Map<String,Object>>();

        Stm = Con.createStatement();

        //query
        ResultSet Result = null;

        boolean Returning_Rows = Stm.execute(q);

        if (Returning_Rows) {
            Result = Stm.getResultSet();
        } else {
            return new ArrayList<Map<String,Object>>();
        }

        //get metadata
        ResultSetMetaData Meta = null;
        Meta = Result.getMetaData();

        //get column names
        int Col_Count = Meta.getColumnCount();
        ArrayList<String> Cols = new ArrayList<String>();
        for (int Index=1; Index<=Col_Count; Index++) {
            Cols.add(Meta.getColumnName(Index));
        }

        while (Result.next()) {
            HashMap<String,Object> Row = new HashMap<String,Object>();
            for (String Col_Name:Cols) {
                Object Val = Result.getObject(Col_Name);
                Row.put(Col_Name,Val);
            }
            Rows.add(Row);
        }

        //close statement
        Stm.close();


        //pass back rows
        return Rows;

    } catch (Exception Ex) {

        System.out.print(Ex.getMessage());
        return new ArrayList<Map<String,Object>>();

    } finally {

        if (Stm != null) {
            Stm.close();
        }
        if (Stm != null) {
            Stm.close();
        }

        System.out.println("Max connections: " + connectionPool.getMaxActive());
        System.out.println("Active connections: " + connectionPool.getNumActive());
        System.out.println("Idle connections: " + connectionPool.getNumIdle());

    }

}

这是每次控制台输出:

DB Connection: 186 ms
Max connections: 10 
Active connections: 1 
Idle connections: 0 

更新:我应该注意,使用它的 Java 应用程序是这样工作的:执行,只运行一个查询并关闭。我想如果 PHP 是这样工作的,并且默认情况下它使用连接池,那么 Java 也应该如此吗?如果我错了,请纠正我。

【问题讨论】:

  • 再一次,无需为一次性应用程序创建连接池。如果您只保留单个连接的引用,那是一个大小为 1 的连接池。我认为您正在困扰 PHP 页面和您自己的 Java 应用程序的性能之间的 200 毫秒差异。
  • 问题是,它是高度使用的应用程序,我说的是每次任何人在大型系统上加载任何页面时都会运行它......每天数十万次。我想把那些完全浪费的200ms剃掉。

标签: java mysql apache-commons


【解决方案1】:

你创建了一个连接池,但你没有往里面放任何东西。您的连接池在创建时是空的,因此您对它的第一次请求保证会创建一个新连接,并且与手动获取连接一样慢。

尝试将您的代码放入一个循环中,在该循环中反复从池中获取连接。尝试一次、五次、十次和十五次。注意结果如何变化。

一些连接池支持自动创建和保存最少个可供使用的连接以及最多个连接。初始化池时,它将预取连接,因此前几次调用不会延迟。

【讨论】:

  • 问题是,该应用程序只运行一个查询,我已经在“更新”中解释了更多。
【解决方案2】:

您不会看到对数据库的单个请求有什么不同。您必须使用多个(并发)请求对此进行测试。

顺便说一句:您遵守 Java 命名约定并以小写开头所有对象。

【讨论】:

    【解决方案3】:

    您可以通过调用connectionPool.addObject() 来预加载您的池。一开始它是空的,只有在您发布查询后才会创建连接。

    【讨论】:

      【解决方案4】:

      您的用例不保证连接池。它只是您需要的一个连接。 您正在使用的池类GenericObjectPool 有一个方法addObject();。这将创建对象并将其添加到池中。这将避免以后创建连接。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-08
        • 1970-01-01
        • 2017-01-24
        • 2014-10-30
        • 2018-09-10
        • 2013-08-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多