On Thu, 31 Jan 2003, shawn wrote:

> Date: 31 Jan 2003 10:35:30 +0900
> From: shawn <[EMAIL PROTECTED]>
> Reply-To: Tomcat Users List <[EMAIL PROTECTED]>
> To: Tomcat Users List <[EMAIL PROTECTED]>
> Subject: DBCP leak ?
>
> As noted in Tomcat docs,
>
> A web application has to explicetely close ResultSet's, Statement's, and
> Connection's.
>
> I am using a web app that opens a ResultSet locally (in a method) but it
> never gets closed (gc'd sometime I presume).
>

In the immortal words of Walt Kelly's POGO comic strip (if you're old
enough to remember):  "we have met the enemy and they is us".  :-)

> Under Oracle, a user is hitting the maximum number of Oracle process and
> I presume it is a leak.
>

Yes ... but it's in your application, not the driver.

> Three questions.
>
> 1) must a local ResultSet be explicitely closed to avoid a leak

Some JDBC drivers will close the ResultSet for you if you close the
associated Statement, but it sounds like you're probably not doing that
either.

Waiting for the GC to roll around and clean up after you (even if that
actually works; I wouldn't be surprised to find JDBC driver bugs in that
area) is still a very bad design choice -- because the resources allocated
to the unclosed objects are tied up for seconds to minutes (until the GC
gets to them) instead of milliseconds (if you explicitly close everything
as soon as you are done with it).

Therefore, an application configured with X database connections in its
pool can serve X simultaneous users (if you close all the time), but
substantially less than X (sometimes even zero) users if you wait for
the GC to clean up.

>
> 2) if I use,             <parameter>
>               <name>logAbandoned</name>
>               <value>true</value>
>             </parameter>
>
> to log the stack trace, where is that log?  Under logs in the usual place for that 
>context.
> I have to tell someone else where to find the log otherwise would just look for it 
>myself (ie I'm not running Oracle).
>

DBCP uses System.out for these logs, which goes to
$CATALINA_HOME/logs/catalina.out unless you've used the "swallowOutput"
attribute on your <Context> element -- in which case, it goes wherever the
<Logger> for your <Context> element puts it.

> 3) If only Oracle shows this behavior what could account for that?
> Diff jvm?  (just curious)
>

Different JDBC drivers and different JVMs definitely behave differently --
but your fundamental design pretty much guarantees that you are going to
have worse performance than you should, on any database driver or any JVM.

You should learn to apply a fundamental design pattern for database
access when using a connection pool:

  DataSource ds = ... acquire a DataSource object ...;
  Connection conn = null;
  Statement stmt = null;
  ResultSet rs = null;
  try {
    conn = ds.getConnection();
    stmt = conn.createStatement();
    rs = stmt.executeQuery("SELECT ...");
    ... use the result set, or pass it to other classes to use ...
  } catch (SQLException e) {
    ... deal with exception ...
  } finally {
    if (rs != null) {
      try {
        rs.close();
      } catch (SQLException e) {
        ;
      }
      rs = null;
    }
    if (stmt != null) {
      try {
        stmt.close();
      } catch (SQLException e) {
        ;
      }
      stmt = null;
    }
    if (conn != null) {
      try {
        conn.close(); // Returns connection to the connection pool
      } catch (SQLException e) {
        ;
      }
      conn = null;
    }
  }

This approach *guarantees* that you will always clean up, no matter when
an SQLException might happen, and means that the code you pass the result
set to doesn't have to worry about cleaning up -- the "finally" block will
take care of that.

> TIA
>
> --
> shawn

Craig

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to