db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Deepa Remesh (JIRA)" <derby-...@db.apache.org>
Subject [jira] Updated: (DERBY-210) Network Server will leak prepared statements if not explicitly closed by the user until the connection is closed
Date Mon, 13 Feb 2006 18:21:26 GMT
     [ http://issues.apache.org/jira/browse/DERBY-210?page=all ]

Deepa Remesh updated DERBY-210:
-------------------------------

    Attachment: derby-210-patch4.diff
                derby-210-patch4.status

Attaching 'derby-210-patch4.diff' which changes the finalizer method in Statement and PreparedStatement
classes in the client driver. Changes are:

1. In PreparedStatement class, the finalizer was calling closeX method, which was doing:
    * Call super.closeX() ---> Statement.closeX()
    * Cleanup parameter objects - parameterMetaData_, sql_, parameters_ array
    * Remove the PreparedStatement from connection_.CommitAndRollbackListeners_ list

   Changes done by patch:
    * Add a new method markClosed() which will free client-side resources. 
    * The new method is named markClosed() to keep it uniform with naming convention in superclass.
    * This method is called from close() and finalize() methods.
    * markClosed() method will call super.markClosed() to perform cleanup of parent class.
It will cleanup the objects specific to PreparedStatement, which are ParameterMetaData and
parameters. It also removes the PreparedStatement form the list in Connection object. 
    
2. In Statement class, the finalizer was calling closeX method, which was doing:
    * Close any open cursors for this statement on the server.
           - If result set is open on server, send CLSQRY to the server.
           - check if autocommit is required when closing result sets and flow a commit to
server, if required
    * Call Statement.markClosed(), which does
             - Mark close the result sets on the client
             - If cursor name was set on the statement, remove it from Connection.clientCursorNameCache_
             - Call markClosed() on prepared statements for auto generated keys
             - Call markClosedOnServer(), which frees up the section. The freed section will
be re-used by new statements.
    * Remove the Statement from Connection.openStatements_ list
    * Cleanup ResultSetMetaData

    Changes done by patch:
        * Move the cleanup of ResultSetMetaData and remove of Statement from Connection.openStatements_
list into markClosed() method. This will keep all client-side cleanup in markClosed().
        * Change the finalizer to just call markClosed(). This method frees up client-side
resources and operates on synchronized collections. So I have removed the synchronize block
from the finalizer. 
     * The autocommit logic does not exist in the finalizer since only markClosed() is called
from finalizer. This will avoid untimely commits which was causing the regression in the test
lang/updatableResultSet.java

With this patch, I ran derbynetclientmats with  Sun JDK1.4.2 on Windows XP.

Just before submitting this, I was re-reading the patch and noticed there is no need to override
close and closeX method in PreparedStatement since these methods are doing exactly same things
as the methods in Statement class. close() method in both classes just call closeX. And closeX
does server-side cleanup and calls markClosed. And markClosed in PreparedStatement calls the
super.markClosed. So there is no need for a close() and closeX() in PreparedStatement. This
is possible because of the name change suggested by Bryan. Thanks again. I hope this change
is okay. I will re-run derbynetclientmats and will submit a revised patch4. 

Bryan, if you get time, I would appreciate if you can look at this patch and let me know if
it covers your comments. 

> Network Server will leak prepared statements if not explicitly closed by the user until
the connection is closed
> ----------------------------------------------------------------------------------------------------------------
>
>          Key: DERBY-210
>          URL: http://issues.apache.org/jira/browse/DERBY-210
>      Project: Derby
>         Type: Bug
>   Components: Network Client
>     Reporter: Kathey Marsden
>     Assignee: Deepa Remesh
>  Attachments: DOTS_ATCJ2_Derby-noPatch.png, DOTS_ATCJ2_Derby-withPatch.png, derby-210-patch1.diff,
derby-210-patch2.diff, derby-210-patch2.status, derby-210-patch3.diff, derby-210-patch4.diff,
derby-210-patch4.status, derby-210-v2-draft.diff, derby-210-v2-draft.status, derbyStress.java
>
> Network server will not garbage collect prepared statements that are not explicitly closed
by the user.  So  a loop like this will leak.
> ...
> PreparedStatement ps;
>  for (int i = 0 ; i  < numPs; i++)
> 	{
> 	 ps = conn.prepareStatement(selTabSql);
> 	 rs =ps.executeQuery();
> 	 while (rs.next())
> 	{
> 	    rs.getString(1);
> 	}
> 	rs.close();
> 	// I'm a sloppy java programmer
> 	//ps.close();
> 	}
> 			
> To reproduce run the attached program 
> java derbyStress
> Both client and server will grow until the connection is closed.
>  
> It is likely that the fix for this will have to be in the client.  The client does not
send protocol to close the prepared statement, but rather reuses the PKGNAMCSN on the PRPSQLSTT
request once the prepared statement has been closed. This is how the server knows to close
the old statement and create a new one.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


Mime
View raw message