正如标题中所说,我的ComboPooledDataSource为每个请求创建一个新的数据库连接,并且永远不会重用或释放连接。我事先在PreparedStatements,ResultSet和Connection上调用close()。我正在使用Tomcat和Amazon AWS Elastic Beanstalk和RDS。相关代码如下:
数据库类:
public class DB {
ComboPooledDataSource dataSource;
public static DB db = new DB();
private DB(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setDriverClass("com.mysql.jdbc.Driver");
String db = System.getProperty("RDS_DB_NAME");
String username = System.getProperty("RDS_USERNAME");
String password = System.getProperty("RDS_PASSWORD");
String hostname = System.getProperty("RDS_HOSTNAME");
String port = System.getProperty("RDS_PORT");
String jdbcURL = "jdbc:mysql://" + hostname + ":" + port + "/" + db + "?user=" + username + "&password=" + password;
dataSource.setJdbcUrl(jdbcURL);
this.dataSource = dataSource;
} catch (PropertyVetoException e) {
e.printStackTrace();
}
}
/**
* Get database name
* @return Databse name
*/
public static String dbN(){
return DATABASE;
}
/**
* Gets the database connection
* @return Database connection
* @throws SQLException
*/
public Connection getDatabase() throws SQLException{
return dataSource.getConnection();
}}
带DB调用的API
@GET
@Path("/{session}")
@Produces("application/json")
public Response getAll(@PathParam("session") String session){
JSONArray response = new JSONArray();
Connection conn = null;
PreparedStatement prepared = null;
ResultSet rs = null;
try {
conn = DB.db.getDatabase();
prepared = conn.prepareStatement("SQL STATEMENT");
prepared.setString(1, session);
prepared.setTimestamp(2, new Timestamp(Time.current()));
rs = prepared.executeQuery();
while(rs.next()){
JSONObject obj = new JSONObject();
obj.put("id", rs.getInt("id"));
obj.put("name", rs.getString("name"));
obj.put("color", rs.getString("color"));
response.put(obj);
}
} catch (SQLException e) {
e.printStackTrace();
return Response.status(500).build();
} finally{
try{
prepared.close();
rs.close();
conn.close();
}
catch (SQLException e){
e.printStackTrace();
}
}
return Response.status(200).entity(response.toString()).build();
}
我一直在研究,但没有找到有效的解决方案。我知道它肯定在调用conn.close()和所有其他函数,但它们实际上都没有被关闭。我完全没有想法,有人知道吗
答案 0 :(得分:0)
我最终放弃了ComboPooledDataSource并创建了自己的基本池和连接包装器。连接包装器包装Connection类,只用布尔值替换close()和isClosed()函数。该池只保留了其中许多,并在检索连接时查找关闭的连接,或者在打开过多时关闭它们。