我在GlassFish上有一个Java-JSF Web应用程序,我想在其中使用连接池 . 因此,我创建了一个 application
范围的bean,为其他bean的 Connection
实例提供服务:
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-related”视图进行一些导航后,应用程序将停止并显示以下内容:
RAR5117:无法从连接池[mysql_testPool]获取/创建连接 . 原因:正在使用的连接等于max-pool-size和expired max-wait-time . 无法分配更多连接 . RAR5114:分配连接时出错:[分配连接时出错 . 原因:正在使用的连接等于max-pool-size和expired max-wait-time . 无法分配更多连接 . ] java.sql.SQLException:分配连接时出错 . 原因:正在使用的连接等于max-pool-size和expired max-wait-time . 无法分配更多连接 .
我正在关闭每种方法中的连接和其他资源 . 应用程序通过独立连接运行一切正常 .
我究竟做错了什么?任何提示或建议将不胜感激 .
2 回答
如果您需要JDBC连接池,为什么不依赖已有的连接池? AFAIK,JDBC连接池在这些Java应用程序服务器中被认为或多或少是标准功能,而IMO,如果您只是对创建应用程序感兴趣,则不应该自己构建它 .
这是一个可以帮助您入门的链接:http://weblogs.java.net/blog/2007/09/12/totd-9-using-jdbc-connection-pooljndi-name-glassfish-rails-application
您可能应该做的是找出如何让您的应用程序使用jndi从池中获取连接 .
该异常表示泄漏数据库连接的应用程序代码的典型情况 . 您需要确保在根据普通JDBC习惯用法的同一方法块中的try-with-resources块中获取所有这些(
Connection
,Statement
andResultSet
) and .或者当你没有使用Java 7时,在
try-finally
块中 . 在finally
关闭它们将保证在例外情况下它们也会关闭 .是的,即使使用连接池,您仍需要自己关闭连接 . 在初学者中,他们认为它会自动处理结束是一个常见的错误 . 这是 not true . 连接池返回一个包装的连接,它在close()中执行类似下面的操作:
不关闭它们会导致连接没有被释放回池中以便重复使用,因此它将一次又一次地获取一个新连接,直到数据库用尽连接,这将导致应用程序崩溃 .
另见:
How often should Connection, Statement and ResultSet be closed in JDBC?
Is it safe to use a static java.sql.Connection instance in a multithreaded system?
Closing JDBC Connections in Pool