Thread: Why does Statement.close() close result set?

Why does Statement.close() close result set?

From
Tom Lane
Date:
I've been trying to get erserver to work with the current JDBC driver,
and finding that it doesn't work very well.  The problem is that there
are many places in which a function creates a Statement, executes it
to get a ResultSet, closes the Statement, and returns the ResultSet to
its caller.  This pattern worked okay in JDBC 7.0, but it fails
completely with the current driver, because Statement.close() thinks
it should close the last result set returned by the statement.

I've been able to sort-of work around this by commenting out the
explicit close calls, but this doesn't really work, because the
created Statement object has no references once control has left
the calling function.  A garbage-collection pass would finalize the
Statement and thereby zap the ResultSet, whether or not there are
still any valid references to the ResultSet.

The above programming pattern seems perfectly valid to me, and
accordingly I think that Statement.close() is broken.  The current
behavior foregoes all the advantages of Java's memory management model
and turns them into liabilities.  Instead of letting garbage collection
do what it's supposed to, the programmer is forced to hang onto
references to one object in order to preserve the validity of a
different object.

Comments?

            regards, tom lane

BTW, the error reported by ResultSet.next() in this situation is
extremely misleading; it gripes about "connection closed" when it
should say "result set closed".

Re: Why does Statement.close() close result set?

From
Kevin Schmidt
Date:
Tom,

A ResultSet object is closed when it's Statement object is closed per
the JDBC spec.  Look at the Javadoc on Statement.close() and it states
"When a Statement object is closed, its current ResultSet object, if one
exists, is also closed."  At a higher level it also says that close
"Releases this Statement object's database and JDBC resources
immediately ..." and the ResultSet is one of those resources.

Kevin

Tom Lane wrote:

>I've been trying to get erserver to work with the current JDBC driver,
>and finding that it doesn't work very well.  The problem is that there
>are many places in which a function creates a Statement, executes it
>to get a ResultSet, closes the Statement, and returns the ResultSet to
>its caller.  This pattern worked okay in JDBC 7.0, but it fails
>completely with the current driver, because Statement.close() thinks
>it should close the last result set returned by the statement.
>
>I've been able to sort-of work around this by commenting out the
>explicit close calls, but this doesn't really work, because the
>created Statement object has no references once control has left
>the calling function.  A garbage-collection pass would finalize the
>Statement and thereby zap the ResultSet, whether or not there are
>still any valid references to the ResultSet.
>
>The above programming pattern seems perfectly valid to me, and
>accordingly I think that Statement.close() is broken.  The current
>behavior foregoes all the advantages of Java's memory management model
>and turns them into liabilities.  Instead of letting garbage collection
>do what it's supposed to, the programmer is forced to hang onto
>references to one object in order to preserve the validity of a
>different object.
>
>Comments?
>
>            regards, tom lane
>
>BTW, the error reported by ResultSet.next() in this situation is
>extremely misleading; it gripes about "connection closed" when it
>should say "result set closed".
>
>---------------------------(end of broadcast)---------------------------
>TIP 8: explain analyze is your friend
>
>


Re: Why does Statement.close() close result set?

From
Peter Kovacs
Date:
And about ResultSet the API documentation says:

"A |ResultSet| object is automatically closed when the |Statement|
object that generated it is closed, re-executed, or used to retrieve the
next result from a sequence of multiple results."

This implies that there is (should be) no valid ResultSets for a
Statement other than the "current" ResultSet. This completes the passage
quoted below.

Peter

Kevin Schmidt wrote:

> Tom,
>
> A ResultSet object is closed when it's Statement object is closed per
> the JDBC spec.  Look at the Javadoc on Statement.close() and it states
> "When a Statement object is closed, its current ResultSet object, if
> one exists, is also closed."  At a higher level it also says that
> close "Releases this Statement object's database and JDBC resources
> immediately ..." and the ResultSet is one of those resources.
>
> Kevin
>
> Tom Lane wrote:
>
>> I've been trying to get erserver to work with the current JDBC driver,
>> and finding that it doesn't work very well.  The problem is that there
>> are many places in which a function creates a Statement, executes it
>> to get a ResultSet, closes the Statement, and returns the ResultSet to
>> its caller.  This pattern worked okay in JDBC 7.0, but it fails
>> completely with the current driver, because Statement.close() thinks
>> it should close the last result set returned by the statement.
>>
>> I've been able to sort-of work around this by commenting out the
>> explicit close calls, but this doesn't really work, because the
>> created Statement object has no references once control has left
>> the calling function.  A garbage-collection pass would finalize the
>> Statement and thereby zap the ResultSet, whether or not there are
>> still any valid references to the ResultSet.
>>
>> The above programming pattern seems perfectly valid to me, and
>> accordingly I think that Statement.close() is broken.  The current
>> behavior foregoes all the advantages of Java's memory management model
>> and turns them into liabilities.  Instead of letting garbage collection
>> do what it's supposed to, the programmer is forced to hang onto
>> references to one object in order to preserve the validity of a
>> different object.
>>
>> Comments?
>>
>>             regards, tom lane
>>
>> BTW, the error reported by ResultSet.next() in this situation is
>> extremely misleading; it gripes about "connection closed" when it
>> should say "result set closed".
>>
>> ---------------------------(end of broadcast)---------------------------
>> TIP 8: explain analyze is your friend
>>
>>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
>
>               http://archives.postgresql.org



Re: [Erserver-general] Why does Statement.close() close result set?

From
Dave Cramer
Date:
Tom,

this is what the spec says for Statement.close()

Releases this Statement object's database and JDBC resources immediately
instead of waiting for this to happen when it is automatically closed.
It is generally good practice to release resources as soon as you are
finished with them to avoid tying up database resources.

Note: A Statement object is automatically closed when it is garbage
collected. When a Statement object is closed, its current ResultSet
object, if one exists, is also closed

Dave

On Fri, 2003-10-10 at 11:21, Tom Lane wrote:
> I've been trying to get erserver to work with the current JDBC driver,
> and finding that it doesn't work very well.  The problem is that there
> are many places in which a function creates a Statement, executes it
> to get a ResultSet, closes the Statement, and returns the ResultSet to
> its caller.  This pattern worked okay in JDBC 7.0, but it fails
> completely with the current driver, because Statement.close() thinks
> it should close the last result set returned by the statement.
>
> I've been able to sort-of work around this by commenting out the
> explicit close calls, but this doesn't really work, because the
> created Statement object has no references once control has left
> the calling function.  A garbage-collection pass would finalize the
> Statement and thereby zap the ResultSet, whether or not there are
> still any valid references to the ResultSet.
>
> The above programming pattern seems perfectly valid to me, and
> accordingly I think that Statement.close() is broken.  The current
> behavior foregoes all the advantages of Java's memory management model
> and turns them into liabilities.  Instead of letting garbage collection
> do what it's supposed to, the programmer is forced to hang onto
> references to one object in order to preserve the validity of a
> different object.
>
> Comments?
>
>             regards, tom lane
>
> BTW, the error reported by ResultSet.next() in this situation is
> extremely misleading; it gripes about "connection closed" when it
> should say "result set closed".
> _______________________________________________
> Erserver-general mailing list
> Erserver-general@gborg.postgresql.org
> http://gborg.postgresql.org/mailman/listinfo/erserver-general
>
>
--
Dave Cramer <Dave@micro-automation.net>


Re: Why does Statement.close() close result set?

From
Oliver Jowett
Date:
On Fri, Oct 10, 2003 at 11:21:45AM -0400, Tom Lane wrote:
> I've been trying to get erserver to work with the current JDBC driver,
> and finding that it doesn't work very well.  The problem is that there
> are many places in which a function creates a Statement, executes it
> to get a ResultSet, closes the Statement, and returns the ResultSet to
> its caller.  This pattern worked okay in JDBC 7.0, but it fails
> completely with the current driver, because Statement.close() thinks
> it should close the last result set returned by the statement.

As others have said, this behaviour is required by the JDBC spec. This
actually makes sense in the general case, as a ResultSet implementation that
doesn't read all data at once may rely on resources managed at the Statement
level for continued operation.

> I've been able to sort-of work around this by commenting out the
> explicit close calls, but this doesn't really work, because the
> created Statement object has no references once control has left
> the calling function.  A garbage-collection pass would finalize the
> Statement and thereby zap the ResultSet, whether or not there are
> still any valid references to the ResultSet.

Actually this should work fine as a ResultSet must hold a reference
(directly or indirectly) to the Statement that created it to implement
ResultSet.getStatement(). The postgresql driver's ResultSet implementation
holds this reference directly in a field of AbstractJdbc1ResultSet. So whatever
GC-related problems you are seeing are likely to have another cause.

Relying on finalization to do resource cleanup can be risky, though, since
it's not guaranteed to happen in a timely fashion (or ever, for that
matter). Witness the fun JDK1.4 has with NIO direct buffers & GC ..

-O

Re: Why does Statement.close() close result set?

From
Paul Thomas
Date:
On 13/10/2003 01:23 Oliver Jowett wrote:
> [snip]
> As others have said, this behaviour is required by the JDBC spec. This
> actually makes sense in the general case, as a ResultSet implementation
> that
> doesn't read all data at once may rely on resources managed at the
> Statement
> level for continued operation.
>
> > I've been able to sort-of work around this by commenting out the
> > explicit close calls, but this doesn't really work, because the
> > created Statement object has no references once control has left
> > the calling function.  A garbage-collection pass would finalize the
> > Statement and thereby zap the ResultSet, whether or not there are
> > still any valid references to the ResultSet.
>
> Actually this should work fine as a ResultSet must hold a reference
> (directly or indirectly) to the Statement that created it to implement
> ResultSet.getStatement(). The postgresql driver's ResultSet
> implementation
> holds this reference directly in a field of AbstractJdbc1ResultSet. So
> whatever
> GC-related problems you are seeing are likely to have another cause.
>
> Relying on finalization to do resource cleanup can be risky, though,
> since
> it's not guaranteed to happen in a timely fashion (or ever, for that
> matter). Witness the fun JDK1.4 has with NIO direct buffers & GC ..


ISTM that calling resultset.getStatement().close() after processing the
resultset might provide a reasonable fix.

--
Paul Thomas
+------------------------------+---------------------------------------------+
| Thomas Micro Systems Limited | Software Solutions for the Smaller
Business |
| Computer Consultants         |
http://www.thomas-micro-systems-ltd.co.uk   |
+------------------------------+---------------------------------------------+

Re: [Erserver-general] Why does Statement.close() close result set?

From
Dave Cramer
Date:
Tom,

this is what the spec says for Statement.close()

Releases this Statement object's database and JDBC resources immediately
instead of waiting for this to happen when it is automatically closed.
It is generally good practice to release resources as soon as you are
finished with them to avoid tying up database resources.

Note: A Statement object is automatically closed when it is garbage
collected. When a Statement object is closed, its current ResultSet
object, if one exists, is also closed

Dave

On Fri, 2003-10-10 at 11:21, Tom Lane wrote:
> I've been trying to get erserver to work with the current JDBC driver,
> and finding that it doesn't work very well.  The problem is that there
> are many places in which a function creates a Statement, executes it
> to get a ResultSet, closes the Statement, and returns the ResultSet to
> its caller.  This pattern worked okay in JDBC 7.0, but it fails
> completely with the current driver, because Statement.close() thinks
> it should close the last result set returned by the statement.
>
> I've been able to sort-of work around this by commenting out the
> explicit close calls, but this doesn't really work, because the
> created Statement object has no references once control has left
> the calling function.  A garbage-collection pass would finalize the
> Statement and thereby zap the ResultSet, whether or not there are
> still any valid references to the ResultSet.
>
> The above programming pattern seems perfectly valid to me, and
> accordingly I think that Statement.close() is broken.  The current
> behavior foregoes all the advantages of Java's memory management model
> and turns them into liabilities.  Instead of letting garbage collection
> do what it's supposed to, the programmer is forced to hang onto
> references to one object in order to preserve the validity of a
> different object.
>
> Comments?
>
>             regards, tom lane
>
> BTW, the error reported by ResultSet.next() in this situation is
> extremely misleading; it gripes about "connection closed" when it
> should say "result set closed".
> _______________________________________________
> Erserver-general mailing list
> Erserver-general@gborg.postgresql.org
> http://gborg.postgresql.org/mailman/listinfo/erserver-general
>
>


Re: [Erserver-general] Why does Statement.close() close result set?

From
Jan Wieck
Date:
Tom Lane wrote:

> I've been trying to get erserver to work with the current JDBC driver,
> and finding that it doesn't work very well.  The problem is that there
> are many places in which a function creates a Statement, executes it
> to get a ResultSet, closes the Statement, and returns the ResultSet to
> its caller.  This pattern worked okay in JDBC 7.0, but it fails
> completely with the current driver, because Statement.close() thinks
> it should close the last result set returned by the statement.
>
> I've been able to sort-of work around this by commenting out the
> explicit close calls, but this doesn't really work, because the
> created Statement object has no references once control has left
> the calling function.  A garbage-collection pass would finalize the
> Statement and thereby zap the ResultSet, whether or not there are
> still any valid references to the ResultSet.
>
> The above programming pattern seems perfectly valid to me, and
> accordingly I think that Statement.close() is broken.  The current
> behavior foregoes all the advantages of Java's memory management model
> and turns them into liabilities.  Instead of letting garbage collection
> do what it's supposed to, the programmer is forced to hang onto
> references to one object in order to preserve the validity of a
> different object.
>
> Comments?

How is the automatic cursor code controlled by setFetchSize() affected
by a Statement.close() before the result set is consumed? Does that need
to use holdable cursors here because in turn the transaction around the
cursor could end sooner than expected?


Jan

--
#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #


Re: [Erserver-general] Why does Statement.close() close result

From
Barry Lind
Date:
Jan Wieck wrote:
> How is the automatic cursor code controlled by setFetchSize() affected
> by a Statement.close() before the result set is consumed? Does that need
> to use holdable cursors here because in turn the transaction around the
> cursor could end sooner than expected?
>
>
> Jan
>

This is an interesting question.  The current logic for cursor backed
result sets will error if you try to access the result set after a
commit/rollback (actually you will get an error when you exhaust the
already fetched values that are in memory and try to fetch more from the
database).

This behavior is allowed by the jdbc spec.  In fact there are methods in
Connection, DatabaseMetaData and Statement dealing with "Result Set
Holdability" as of jdbc3/jdk1.4.

Most of these methods are currently not implemented by the jdbc driver
however.  And further more the nature of the methods are such that they
envision the 'holdability' setting to be one set at the Connection
level, as opposed to something that might vary from ResultSet to
ResultSet as it would need to in our current implementation.

We could support ResultSets being usable across transaction boundaries
for both the regular and cursor backed cases if WITH HOLD was used for
7.4 servers.  I would be inclined to think that we would do this only if
the client insisted on requiring cursors be held over transaction
boundaries.  Given what I remember of the implementation discussions on
WITH HOLD, I wouldn't want that to be the default (or am I remembering
it wrong and WITH HOLD doesn't have any adverse side effects that might
be nasty).

thanks,
--Barry



Re: [Erserver-general] Why does Statement.close() close result

From
Oliver Jowett
Date:
(cc: list trimmed)

On Tue, Oct 14, 2003 at 06:08:02PM -0700, Barry Lind wrote:

> Most of these methods are currently not implemented by the jdbc driver
> however.  And further more the nature of the methods are such that they
> envision the 'holdability' setting to be one set at the Connection
> level, as opposed to something that might vary from ResultSet to
> ResultSet as it would need to in our current implementation.

Actually you can specify holdability per statement, much like resultset type
and concurrency -- see:

  http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Connection.html#createStatement(int,%20int,%20int)

-O

Re: [Erserver-general] Why does Statement.close() close result

From
Jan Wieck
Date:
Barry Lind wrote:

> Jan Wieck wrote:
>> How is the automatic cursor code controlled by setFetchSize() affected
>> by a Statement.close() before the result set is consumed? Does that need
>> to use holdable cursors here because in turn the transaction around the
>> cursor could end sooner than expected?
>>
>>
>> Jan
>>
>
> This is an interesting question.  The current logic for cursor backed
> result sets will error if you try to access the result set after a
> commit/rollback (actually you will get an error when you exhaust the
> already fetched values that are in memory and try to fetch more from the
> database).

Only >= 7.4. Everything before just gives a NOTICE but otherwise just
returns "FETCH 0" or "CLOSE" as if the cursor would exist. It does that
even for cursors that have never been declared.


Jan

--
#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #