Subject Re: [IBO] "Transaction has already been started"
Author Helen Borrie
At 02:18 PM 24/08/2003 -0500, you wrote:
>I've the following error "Transaction has already been started" (when an
>exeption has been raised before) as result of this code:
>
>
>DBO_DataModule.IB_Transaction1.StartTransaction;
>FSQLCommand.InsertSQL.Text := sSQL;
>
> try
>
> FSQLCommand.ExecSQL(ukInsert);
> DBO_DataModule.IB_Transaction1.Commit;
>
> except
>
> {this line do not closes transaction}
> DBO_DataModule.IB_Transaction1.CancelAll;

Correct. It does not "close" or cancel or end the transaction. It cancels
any unposted work in the datasets that are associated with the transaction.


> {this line closes all queries too}
> DBO_DataModule.IB_Transaction1.Close;

Correct. That is what the Close method of the transaction is for.

> end;
>
>
>How to close a TIB_Transaction component without have the same effect on the
>Queries asociated with it?

The Close method of a transaction tries to commit any outstanding work; if
this fails, then it cancels the work (all of it), rolls back the
transaction and closes the datasets. Don't call IB_Transaction.Close
unless that is what you want to happen. It is usually called as part of
the destruction sequence when the form or application shuts down.

If a transaction cannot commit for some reason, then the most usual way to
deal with it will be to roll it back and then proceed to fix whatever it
was that caused the failure. That means you need to trap the exception and
get the user back to a position where the work can be corrected and
presented in a fresh transaction.

Going back to the subject of this email, you get the "Transaction has
already been started" if you try to start a transaction in a transaction
object that already has a started transaction. Whenever you call
StartTransaction, you need to test to ensure that the container is not
already managing an active transaction, i.e.

with DBO_DataModule.IB_Transaction1 do
begin
if not TransactionIsActive then
StartTransaction
else
{here you have to deal with the unresolved transaction}.

But there is more trouble here. This looks really weird:

FSQLCommand.InsertSQL.Text := sSQL;

try

FSQLCommand.ExecSQL(ukInsert);
DBO_DataModule.IB_Transaction1.Commit;

What kind of object is FSQLCommand? What are you trying to do here?

At best, this is some kind of unprepared statement, that throws exception
because the ???whatever object doesn't know what it is supposed to commit.

Helen