代码之家  ›  专栏  ›  技术社区  ›  Daniel Szalay

JDBCmysql连接池实践,避免连接池耗尽

  •  10
  • Daniel Szalay  · 技术社区  · 16 年前

    我在GLAISFISH上有一个JavaJSF Web应用程序,在其中我想使用连接池。因此我创造了一个 application 有范围的豆子 Connection 其他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_testpool]获取/创建连接失败。原因:正在使用的连接等于最大池大小和过期的最大等待时间。无法分配更多连接。RAR5114:分配连接时出错:[分配连接时出错。原因:正在使用的连接等于最大池大小和过期的最大等待时间。无法分配更多连接。]java.sql.sqlException:分配连接时出错。原因:正在使用的连接等于最大池大小和过期的最大等待时间。无法分配更多连接。

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

    我做错什么了?如有任何建议或建议,我们将不胜感激。

    2 回复  |  直到 10 年前
        1
  •  20
  •   Community Mohan Dere    9 年前

    Connection Statement ResultSet try-with-resources

    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();
        }
    }
    

    try-finally 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) {}
        }
    }
    

    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();
        }
    }
    

    推荐文章