Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JDBCMySQL连接池实践,以避免耗尽连接池_Java_Mysql_Jdbc_Glassfish_Connection Pooling - Fatal编程技术网

Java JDBCMySQL连接池实践,以避免耗尽连接池

Java JDBCMySQL连接池实践,以避免耗尽连接池,java,mysql,jdbc,glassfish,connection-pooling,Java,Mysql,Jdbc,Glassfish,Connection Pooling,我在GlassFish上有一个Java JSF Web应用程序,我想在其中使用连接池。因此,我创建了一个应用程序作用域bean,它为其他bean提供连接实例: public class DatabaseBean { private DataSource myDataSource; public DatabaseBean() { try { Context ctx = new InitialContext(); e

我在GlassFish上有一个Java JSF Web应用程序,我想在其中使用连接池。因此,我创建了一个
应用程序
作用域bean,它为其他bean提供
连接
实例:

public class DatabaseBean {

    private DataSource myDataSource;

    public DatabaseBean() {
        try {
            Context ctx = new InitialContext();
            ecwinsDataSource = (DataSource) ctx.lookup("jdbc/myDataSource");
        } catch (NamingException ex) {
            ex.printStackTrace();
        }
    }

    public Connection getConnection() throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException {
        Connection connection = myDataSource.getConnection();
        System.out.println("Succesfully connected: " + connection);
        //Sample: Succesfully connected: com.sun.gjc.spi.jdbc40.ConnectionHolder40@7fb213a5
        return connection;
    }
}
这样,连接池很快就会被填满;在“db相关”视图中进行几次导航后,应用程序将停止并显示以下内容:

RAR5117:无法从连接池[mysql\u testPool]获取/创建连接。原因:正在使用的连接等于最大池大小和过期的最大等待时间。无法分配更多连接。RAR5114:分配连接时出错:[分配连接时出错。原因:正在使用的连接等于最大池大小和过期的最大等待时间。无法分配更多连接。]java.sql.SQLException:分配连接时出错。原因:正在使用的连接等于最大池大小和过期的最大等待时间。无法分配更多连接

我正在用各种方法关闭连接和其他资源。应用程序在独立连接下运行正常


我做错了什么?任何提示或建议都将不胜感激。

此异常表示应用程序代码泄漏数据库连接的典型情况。您需要确保按照正常的JDBC习惯用法,在同一个方法块中的块中获取并关闭它们(
连接
语句
结果集

public void create(Entity entity) throws SQLException {
    try (
        Connection connection = dataSource.getConnection();
        PreparedStatement statement = connection.prepareStatement(SQL_CREATE);
    ) { 
        statement.setSomeObject(1, entity.getSomeProperty());
        // ...
        statement.executeUpdate();
    }
}
或者当您不使用Java 7时,在
try finally
块中。最后在
中关闭它们将保证在异常情况下也会关闭它们

public void create(Entity entity) throws SQLException {
    Connection connection = null;
    PreparedStatement statement = null;

    try { 
        connection = dataSource.getConnection();
        statement = connection.prepareStatement(SQL_CREATE);
        statement.setSomeObject(1, entity.getSomeProperty());
        // ...
        statement.executeUpdate();
    } finally {
        if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
        if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
    }
}
是的,即使使用连接池,您仍然需要自己关闭连接。这是一个常见的错误,发起者认为,它会自动处理关闭。这是不正确的。连接池即返回一个包装的连接,该连接在close()中执行以下操作:

不关闭它们将导致连接无法释放回池中以供重用,因此它将一次又一次地获取新连接,直到数据库耗尽连接,从而导致应用程序崩溃

另见:

如果您需要JDBC连接池,为什么不依赖现有的连接池呢?顺便说一句,JDBC连接池在这些java应用服务器中或多或少被认为是一个标准特性,在我看来,如果您只是对创建应用程序感兴趣,您不应该自己构建它

这里有一个链接可以帮助您开始:


您可能应该做的是了解如何让您的应用程序使用jndi从池中获取连接。

他已经在这么做了吗?他已经在appserver中配置了连接池数据源。他只是没有按照例外情况正确关闭资源。感谢您的全面回答,这真的很有帮助!我用app-modifications编辑了我的评论。再次感谢您提供的精彩信息!
public void close() throws SQLException {
    if (this.connection is still eligible for reuse) {
        do not close this.connection, but just return it to pool for reuse;
    } else {
        actually invoke this.connection.close();
    }
}