Board index » delphi » Re: Is This a WTF, or Just Captain Jake Being Dense?

Re: Is This a WTF, or Just Captain Jake Being Dense?


2006-09-21 07:41:36 PM
delphi50
Oh, I didn't realize there were any that didn't. Does that mean you have to
manually close all open datasets on a data module, for instance, or you'll
get exceptions when freeing the DM?
CoreLab has added a handy property to their components named AutoClose which
addresses that point to some extent. When the property is set, it closes the
db cursor after all the records have been fetched. Very useful for lookup
tables and such since Closing the dataset throws away all the query results.
"Eric Grange" <XXXX@XXXXX.COM>writes
Quote
>A possible improvement.. there's no need to wrap the DataSet.Open / Close
>in a block because DataSet.Free also Closes the dataset.

This isn't a requirement of all datasets, ours f.i. systematically barf if
they haven't been closed by the time your free them.
This is to prevent datasets being "forgotten" in an open state (and thus
squandering DB resources, both client and server side, when they're not
causing trouble with transactions).
 
 

Re: Is This a WTF, or Just Captain Jake Being Dense?

Quote
Oh, I didn't realize there were any that didn't. Does that mean you have to
manually close all open datasets on a data module, for instance, or you'll
get exceptions when freeing the DM?
Yep, that is the whole point.
But freeing the DM (or a manually allocated dataset) can happen a bit
too late, so we also have warnings logged if a dataset was left open for
an inordinate amount of time (but still closed before being freed), and
if you have too many datasets open at a time (usually a sign of
something done wrong).
Quote
CoreLab has added a handy property to their components named AutoClose which
addresses that point to some extent. When the property is set, it closes the
db cursor after all the records have been fetched. Very useful for lookup
tables and such since Closing the dataset throws away all the query results.
We had an autoclose a long time ago, but discarded it because it
resulted in more maintainance trouble than it was worth (you couldn't
always tell which autoclose value was correct out of the blue, there
were problems with property not adjusted after copy-pastes, etc.)
Now we have a simple rule, that can be enforced and verified easily.
Manually closing is a small amount of code, a few seconds of typing, a
completely negligible time investment compared to the somewhat random
and hard to reproduce trouble that arose from keeping too many
connections or maintaining unnecessary db stuff open (and their implicit
locks, higher load on servers, etc.).
As a bonus, it forces to think about context and purpose, which is good
in different ways :)
Eric
 

Re: Is This a WTF, or Just Captain Jake Being Dense?

Interesting way to handle those problems. I assume you're using sqlserver
which, if I recall, allows only one open cursor per connection. For small
lookup datasets used on forms that users are likely to keep open for long
periods of time, you manually load them into a memory based dataset?
"Eric Grange" <XXXX@XXXXX.COM>writes
Quote
>Oh, I didn't realize there were any that didn't. Does that mean you have
>to manually close all open datasets on a data module, for instance, or
>you'll get exceptions when freeing the DM?

Yep, that is the whole point.
But freeing the DM (or a manually allocated dataset) can happen a bit too
late, so we also have warnings logged if a dataset was left open for an
inordinate amount of time (but still closed before being freed), and if
you have too many datasets open at a time (usually a sign of something
done wrong).

>CoreLab has added a handy property to their components named AutoClose
>which addresses that point to some extent. When the property is set, it
>closes the db cursor after all the records have been fetched. Very useful
>for lookup tables and such since Closing the dataset throws away all the
>query results.

We had an autoclose a long time ago, but discarded it because it resulted
in more maintainance trouble than it was worth (you couldn't always tell
which autoclose value was correct out of the blue, there were problems
with property not adjusted after copy-pastes, etc.)
Now we have a simple rule, that can be enforced and verified easily.

Manually closing is a small amount of code, a few seconds of typing, a
completely negligible time investment compared to the somewhat random and
hard to reproduce trouble that arose from keeping too many connections or
maintaining unnecessary db stuff open (and their implicit locks, higher
load on servers, etc.).
As a bonus, it forces to think about context and purpose, which is good in
different ways :)

Eric
 

Re: Is This a WTF, or Just Captain Jake Being Dense?

Aleksander Oven writes:
Quote
Wayne Niddery [TeamB] writes:
>Of course in the case of an exception there is also a memory leak
>here. The correct code would of course be:
>
>while not aDataset.EOF do
>try
>// do stuff
>aDataset.Next;
>finally
>aDataset.Close;
>aDataset.Free;
>end;

This code would result in AV on second iteration, because the way
you wrote it, the finally section executes as part of the loop.
Oops, so right. that is what happens when you copy/paste and try to tweak, I
meant to add a begin/end for the while loop - and the entire loop should be
in the try/finally.
I'm not doing well on this particular thread! <g>
--
Wayne Niddery - Winwright, Inc (www.winwright.ca)
"The purpose of morality is to teach you, not to suffer and die, but to
enjoy yourself and live." - Ayn Rand
 

Re: Is This a WTF, or Just Captain Jake Being Dense?

Quote
Interesting way to handle those problems. I assume you're using sqlserver
which, if I recall, allows only one open cursor per connection.
Actually we're on FireBird and Oracle.
You can keep many cursor open, but most of the time, the structural
overhead of doing so (server + network + db driver + dataset) is quite
larger than the data itself.
Quote
For small lookup datasets used on forms that users are likely to keep
open for long periods of time, you manually load them into a memory
based dataset?
Something like that, but without DB-aware controls (which disappeared
from our UIs some time in the last century), so instead of loosely typed
generic memory datasets, there are strongly typed objects lists and the
like.
Eric