Tomcat JDBC connection pool issue: “Statement is closed”

六眼飞鱼酱① 提交于 2019-12-01 11:24:59
jmpenetra

I created the bounty to help out Reznik but I ended up figuring out what the problem was by looking at his code.

The problem is that every time a new connection is fetched from the pool in

protected Connection getDbConnection() throws Exception
{
    dbConn = dataSource.getConnection();
    return dbConn;
}

the object dbConn is updated to a new connection.

Example:

T1 invokes getDbConnection()

T2 invokes getDbConnection()

T1 executes the query, processes the resultSet and calls shutdown()

public void shutdown() {
    if (this.dbConn != null) 
        this.dbConn.close();
}

Because T2 updated the object, the connection being used by T2 will be shutdown by T1

T2 tries to use the connection but it is already closed.

This way, instead of always updating the connection, just return it and then add the extra logic to close the connection that was fetched from the pool.

Elliott Frisch

I notice two things:

1) connProperties.setTestOnReturn(false); which should be changed to true. Otherwise your connection isn't necessarily valid. And you might not get notified until you receive an invalid Statement.

2) You should ALWAYS close your ResultSet, Statement and Connection objects. It does involve a lot of boilerplate, or you could use my static Close utility method.

1) protected CallableStatement executeCSqlQuery(String sql) throws Exception returns the callable statement. If you are trying to use it again after closing it inside the method, you'll probably get that error. All the processing involving that object should be done before closing it.

2) The same method has a catch(SQLException ){throw e}. You'd either want to handle the exception there, or if you want to propagate it remove the try-catch

3) I can see in the last piece of code rs = cstmt.getResultSet(); It is always a good practice to close the resources in the inverse order that they were obtained, as you've read in the post you linked for Peter. So rs.close(); cstmt.close(); connection.close();. It's not included in your sample, but if you're returning the ResultSet after closing it, you'll have the same problem described at 1)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!