Hi,

> Elli,
>
> On 11/4/2009 7:01 PM, Elli Albek wrote:
>> I also
>> remember that closing a connection closes statements and result sets, but it
>> has been a while since I read the source.
>
> Pooled connections are almost certainly not behaving this way. This has
> been discussed at least twice in the last week or two, and, I believe,
> already once in this thread.
>
> - -chris

This is certainly not the case for my DBCP library (1.2.2). I just
stepped through the source code: Calling connection.close() is closing
result sets and statements. In addition I commented the code that
closes statements and result sets in our framework to create a leak,
and DBCP closed everything. Relevant DBCP Code snippets below.

Josh:
You are correct, wrapping connections, statements and datasources is
not a good idea. It is complicated code and can lead to many problems.
Fortunately for you, you don’t have to do that. You can recklessly
leave statements and result sets open, and as long as you call
connectiohn.close() at the end DBCP will do all the work for you. You
can verify this by downloading the source code, and putting a break
point just before you call close.

I am telling you this based on experience. We do wrap everything for
logging purpose (data source, connection, statement). Doing it was far
from trivial, even using the DBCP ready-to-use wrapper classes
(DelegatingConnection, DelagatingStatement…).

Of course is it good to follow best practices and close things as soon
as possible in finally blocks. But in your case, it may just be an
unnecessary intermediary step that you can skip. Maybe you can start
with a brute force filter and rely on the good fellows that wrote DBCP
to clean up the mess. Then go to a better solution, where you use a
framework that does most of this work for you. There are too many java
database frameworks to list, some of them are heavy, some are minimal
right above the JDBC layer, and still provide automatic closing of
resources.

Below is the DBCP code that keeps track of open statements/result sets
and closes them when the connection is closed (BDCP 1.2.2).

PollableConnectionFactory:
public void passivateObject(Object obj) throws Exception {
  ...
  if(obj instanceof DelegatingConnection) {
    ((DelegatingConnection)obj).passivate();
  }
}

DelegatingConnection (called via subclass PollableConnection):

    protected void passivate() throws SQLException {
        try {
            // The JDBC spec requires that a Connection close any open
            // Statement's when it is closed.
            List statements = getTrace();
            if( statements != null) {
                Statement[] set = new Statement[statements.size()];
                statements.toArray(set);
                for (int i = 0; i < set.length; i++) {
                    set[i].close();
                }
                clearTrace();
            }
            setLastUsed(0);
            if(_conn instanceof DelegatingConnection) {
                ((DelegatingConnection)_conn).passivate();
            }
        }
        finally {
            _closed = true;
        }
    }

Delegating statement:
    public void close() throws SQLException {
        try {
            try {
                if (_conn != null) {
                    _conn.removeTrace(this);
                    _conn = null;
                }

                // The JDBC spec requires that a statment close any open
                // ResultSet's when it is closed.
                // FIXME The PreparedStatement we're wrapping should
handle this for us.
                // See bug 17301 for what could happen when ResultSets
are closed twice.
                List resultSets = getTrace();
                if( resultSets != null) {
                    ResultSet[] set = (ResultSet[])
resultSets.toArray(new ResultSet[resultSets.size()]);
                    for (int i = 0; i < set.length; i++) {
                        set[i].close();
                    }
                    clearTrace();
                }

                _stmt.close();
            }
            catch (SQLException e) {
                handleException(e);
            }
        }
        finally {
            _closed = true;
        }
    }

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to