Subject RE: [IBO] Phantom connections?
Author Jason Wharton
If you would, please try and decipher exactly what the contents of the teb
is when that call is made so we can rule out IBO or the server as the source
of the problem. If the teb is the same then the problem is under the hood.
If the teb is different then it is something IBO is doing weird.

Jason Wharton
www.ibobjects.com


> -----Original Message-----
> From: Josh Higgs [mailto:Josh@...]
> Sent: Wednesday, December 01, 2004 12:04 AM
> To: IBObjects@yahoogroups.com
> Subject: [IBO] Phantom connections?
>
>
>
> Morning all
>
> Interbase WI-06.0.1.6
> Delphi 5
> IBObjects (4 something - how do I tell?)
>
> I have a utility that requires exclusive use to a database
> because the .gdb
> will be renamed moved etc. Hence, just prior to that action,
> it checks to
> ensure that the file is not in use. Even before that, it
> connects to the
> .gdb, does a couple of queries, and then disconnects.
>
> The problem is that it (sometimes, on some customer sites),
> it reports the
> database is in use. The reason for this is because in the
> connection/queries/disconnection process, IB_Objects is
> creating not one,
> but two connections to the database, and releases only one on
> disconnection.
>
> The source code looks a bit like this:
>
> function TdmUpgrade.GetDatabaseRelease(
> DatabaseObject: TDatabaseObject): TFileVersion;
> var
> lVersionI : integer;
> begin
>
> if txnUpgrade.intransaction then
> raise Exception.create('txnUpgrade.intransaction in
> TdmUpgrade.GetDatabaseRelease');
>
> //At this point Interbase properties reports 0 attachments to 0
> databases - OK
>
> ConnectSystemDatabase(DatabaseObject);
> try
> //At this point Interbase properties reports 1 attachment to 1
> database - OK
> txnUpgrade.starttransaction;
> try
>
> if VersionExists then //This function call creates
> another attachment
> lVersionI := qryVersionExists.GeneratorValue('GEN_VERSION', 0)
> else
> lVersionI := 0;
> result := VersionIntToFV(lVersionI);
>
> finally
> if txnUpgrade.intransaction then
> txnUpgrade.commit;
> end; //try..finally for txnUpgrade.commit;
> finally
>
> //At this point Interbase properties reports 2
> attachments to 1 database
> DisconnectSystemDatabase;
> //At this point Interbase properties reports 1
> attachments to 1 database
> end; //try..finally for database disconnection
> end;
>
> function TdmUpgrade.VersionExists: boolean;
> begin
>
> result := false;
>
> try
> with qryVersionExists do
> begin
> close;
> //At this point Interbase properties reports 1 attachment to 1
> database - OK
> open;
> //At this point Interbase properties reports 2 attachments to 1
> database - NOT OK
> if fieldbyname('rdb$generator_name').isnull then
> exit;
> result := true;
> end; //with qryVersionExists do
> finally
> qryVersionExists.close;
> end; //try..finally for qryVersionExists.close;
>
> //At this point Interbase properties reports 2 attachments
> to 1 database -
> NOT OK
>
> end;
>
> It is the open call that creates the second attachment.
>
> qryVersionExists is a TIB_Cursor
> qryVersionExists.IB_Transaction = txnUpgrade
> qryVersionExists.IB_Connection = ibcSystemDatabase (which is
> the one that
> gets connected in ConnectSystemDatabase)
> txnUpgrade.IB_Connection = ibcSystemDatabase
> qryVersionExists.IB_Session = ibsSystemDatabase
> txnUpgrade.IB_Session = ibsSystemDatabase
> ibsSystemDatabase.DefaultConnection = ibcSystemDatabase
> qryVersionExists, txnUpgrade, ibcSystemDatabase and
> ibsSystemDatabase all
> exist on the same datamodule with ibsSystemDatabase being
> created first.
>
> The second connection is being created with a call to
> isc_start_multiple in
> TIB_Transaction.API_Start - the call stack is as follows:
>
> TIB_Transaction.API_Start
> TIB_Statement.SysStart
> TIB_Statement.CheckTransaction(true)
> TIB_Statement.SysExecute
> TIB_Dataset.SysExecute
> TIB_Dataset.SysOpen
> TIB_Dataset.Open
> TdmUpgrade.VersionExists
> TdmUpgrade.GetDatabaseRelease($197B560) <- pointer to my
> DatabaseObject
>
> A clip from APIStart is executing this code:
>
> with IB_Session do
> begin
> errcode := isc_conn_lost;
> ticks := GetTickCount + 2000;
> while ( errcode = isc_conn_lost ) and ( ticks >
> GetTickCount ) do
> errcode := isc_start_multiple( @status,
> PtrHandle,
> ConnectionCount,
> pteb );
> <-------------- extra connection created here
> if errcode <> 0 then HandleException( Self );
> end;
>
>
> I do not understand why starting a transaction would create another
> connection when it already has one. The crazy thing is that
> it doesn't
> happen all the time, but (at the moment) I can reproduce it relatively
> reliably with a particular customer's database.
>
> After disconnection, the remaining 1 attachment to 1 database is not
> released for a couple of minutes, but by then my program has
> long since
> decided that the file is already in use.
>
> Any ideas?
>
> Thanks
>
>
>
> Josh