tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Josh Gooding <josh.good...@gmail.com>
Subject Re: ConnectionPool question
Date Fri, 06 Nov 2009 14:31:00 GMT
So with this being said, and I have to ask now the following questions:

1 - with statements that are returned directly (return
ConnectionPool.getConnection().prepareStatement(sqlStatement);) how do I
close the connection?  Since there are no finally blocks to close the
connection in the method on the backend, would I do this in the presentation
layer, and just do a rs.getStatement().getConnection().close();?  (or
something like that?)

2 - Should each of my methods that call the DB and extract a string,
integer, etc, have the "getConnection" in that particular method grab the
info and then close the connection in the same method?

3 - Since I fixed / updated / and realized now it's a bad idea to write a
wrapper for the CP, what do I do to get a connection?  Since I'll not be
using the CP Wrapper anymore.  Would it be importing the datasource class
and doing a ds.getConnection() right there in each method?

4- For my dumb curiosity what problems can it lead to?

- Josh

On Thu, Nov 5, 2009 at 10:37 PM, Elli Albek <elli@sustainlane.com> wrote:

> 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-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message