Subject Re: [IBO] How to clean up resources at closing program ?
Author Helen Borrie
At 12:35 PM 18/08/2003 +0200, you wrote:
>Sorry, for the previous e-mail I was to fast with clicking send
>
>Thanks Helen, but still there is something unclear for me
>
> > No, in a clean application, the opposite. Connection.Disconnect will
> > ensure that the transactions associated with it will be made to do their
> > cleanup. Connection.Disconnect will ultimately get called by the owner of
> > the connection, anyway.
>
>OK, so you mean that in the most simple case
>the destructor of the connection (that is automatcally called at destruction
>of it's owner)
>will call a Disconnect and this in it's turn will ensure that the
>transactions do a cleanup
>But how does this work ? By calling the unprepare an close functions of the
>Dataset functions ?

This will happen in due course if the dataset is still instantiated.

>If so, then why can the dataset components not call this in their own
>destructor ?

They do - if there are resources in use when their destructor gets called,
e.g. you destroy a form that owns them. There is nothing to say you
shouldn't do that.

We're talking about two different things here. Datasets being created and
destroyed, as contrasted with datasets being prepared/unprepared/finished
returning rows, i.e. cleaning up resources (that was what your question was
about). Transaction.Close() takes care of the latter but not of the
former. The owners of the datasets will call their destructors. So, if
you're careless about ensuring that the destructor is called, the data
resources will get cleaned up down the line, but the datasets themselves
could still sit there.

> > This is a propos one part of your question, which was about having query
> > objects located on a different form to the connection object. This is just
> > fine as long as you keep to the basic Delphi rules of ensuring that
>objects
> > are always able to destroy their own creations without interference.
>
>Yes, but what do you mean specifically in the case of Connection and Dataset
>components
>Do you mean with this that the Dataset components should not be destroyed
>before
>the Connection and Transaction components ?

No. It means that datasets should not be left with resources that refer to
transaction or connection components that have already been destroyed.


>I guess that what I want to know about the magic behind the screens is, if
>each component
>(TIB_Transaction, TIB_Connection and Dataset components) clean up their own
>things
>independently or if they need each other, which implies that there should
>alway be a specific
>creation and thus destruction order of the components
>And If the latter is the case then what is the specific creation order ?

OK, the "bomb-proof" creation order is to create the session first, then
the connection, then the transactions, then the datasets. This applies
overall, or module by module, according to the architecture of your
app. If some module in your app creates instances of a data-aware module,
then it ought to call its destructor. In many applications you have the
creation of a set of DAOs "embedded" inside a broader set of objects. If
you can visualise that, then you will see my point about not overlapping or
meshing dependencies...always providing a clean backward track through the
destructors.

Now, that doesn't mean that the "bomb-proof" order is the only possible or
safe order (other than the need to have the session created first). You
can create objects on the fly, which is just fine, as long as you also take
care of destroying them within the same scope in which they were created.

btw, not to confuse you about the session: normally, IBO automatically
creates an IB_Session automatically, as a precursor to creating the first
data access object. Then, all data access objects will share that
IB_Session by default.

If your datamodule, webmodule, whatever, is for threaded use then you have
to make sure to have the IB_Session created explicitly instead, so that it
won't be shared by other threads. All DAOs that are instantiated then
chain down from it and belong to that instance of the IB_Session. This
matters, e.g. for ISAPI modules.

In an MDI application, the default session is shared by all DAOs created,
and you don't have to be concerned about it. And, as a general rule, if
you take good care with the creation order of things, then the resource
cleanup will also be good. IOW, just follow good Delphi practice and the
DAO cleanup will ride on it.

This topic seems to have ended up being a bit overcooked - my fault, no
doubt. :-)

Helen