Subject Re: [IBO] Transaction Timeout w/Multithreaded app
Author riaan_bosch <riaan@northbridge.co.za>
Bjørge,

My experience with IBO / transactions / multi-threading (IBO 3.6Dg -
currently looking at IBO4) which I post here as much as to get
comments as to be of possible assistance...

1. All IBO components in a thread (for a multi-threaded app.) should
be linked to a TIB_Session component that is unique to each thread.
The abbreviated code sequence (each thread)

IB_Session = new TIB_Session(NULL);
IB_Connection = new TIB_Connection(IB_Session);
IB_Query = new TIB_Query(IB_Session);

Maybe the frozen GUI had something to do with sharing the default
sesssion among the threads in the application?

2. The automatic commit of transactions has to do with a timer event
being managed by the session (if this is not correct, please
comment). For explicitly created sessions, this timer event is
disabled; quoting from the help file :
(TIB_Session.TimerInterval) "For explicit sessions the default is 0
which disables the timer. This is because some models of threading
may not work with the timer. So, I have it disabled in order to avoid
problems."

3. The problem I have is that the transaction started by IBO when
reading stuff from the system tables when the first query is opened,
does not get closed as is the usual case. The result was that
the 'oldest transaction' got stuck, leading to problems with garbage
collection. The workaround (which I don't like) is to use the
connection's 'Transaction[]' property to commit all transactions at
a point in the software where I know there shouldn't be any open
transactions.

4. I believe that IB7 is 'thread-safe' - will that change the
approach in using IBO with multi-threaded applications?

Best regards
Riaan Bosch

--- In IBObjects@yahoogroups.com, "Bjørge Sæther" <bjorge@i...> wrote:
> "Helen Borrie" <helebor@t...> skrev i melding
> news:5.1.0.14.2.20030221005505.0308cff8@m...
>
> (I'm sorry, my OE crashes when I answer those messages, had to
paste this
> text into a new, fresh message)
>
> > At 02:27 PM 20/02/2003 +0100, you wrote:
> >
> > > >
> > > > At 11:19 20.02.2003 +0100, you wrote:
> > > > >Q#2: How should I use transactions to avoid trouble and
minimize need
> for
> > > > >database sweeps ?
> > >
> > >Yes. They explain much about handling transactions, but nothing
about
> what
> > >to do if you need to change the Timeout stuff. It seems like
I've fixed
> it
> > >by now, but only with a workaround that I really don't fancy.
> > >Wouldn't a simple boolean property "UseTimeouts" or something
like that
> be
> > >appropriate ?
> >
> > The *answer* to this question is in being able to time out a
> > transaction. Or, to look at it from another angle, if you allow
> > transactions to run indefinitely, you will get both trouble AND
sweeps.
>
> I don't need them to run indefinately, I just need to allow them to
run for
> more than 2 minutes, or avoid the transaction locking at the
Api_Commit
> call.
> It was urgent to get around this, so I had to do a dirty source code
> modification for now (Setting a longer interval in
TIB_Transaction.Create).
> This is no solution, but it works for now.
>
> > You have a set of properties called TimeoutProps. Read the doc
for
> > TIB_TimeoutProps to see how to manipulate these settings.
>
> The problem, obviously, is to be able to change settings in the
*correct*
> TimeoutProps. Or - more specific - to understand *what* the
different
> TIB_Transaction components are doing.
> I believe I've figured out that I need to create an explicit
transaction
> component to use within the thread. I may be wrong about this. Now,
it is
> not *this* transaction that causes my problems, as it has its
TimeoutProps
> set to keep it from doing anything as long as a procedure is
running. It's
> the Internal Transaction, I believe.
>
> > Did you manage to sort out your apparent confusion as to what a
deadlock
> > is? A deadlock isn't caused by a timeout, nor resolved by
changing
> timeout
> > settings, as a rule, but by changing to a more suitable
combination of
> > isolation level and lockwait settings, such that an exception is
returned
> > to the client. It's my guess that (unless the engine is actually
> returning
> > a deadlock exception) you are getting a livelock, where your two
worker
> > threads are waiting for each other interminably. You *need* to
get into a
> > deadlock situation, so that your application can respond to the
exception
> > by rolling back the transaction in one thread in order to permit
the other
> > to commit.
>
> "Deadlock" is a term also used with threads in a usual GUI
application as
> well. I've never heard about "livelock", but I wouldn't say that
anyone
> using different terms from me is "apparently confused".
> First, I don't want any exception to be thrown, as there is nothing
wrong.
> Secondly, I don't need the transaction to perform any timeout
actions, as I
> know exactly when to do a commit, namely *after* the procedure is
executed.
> There is noone else messing with database when the procedures are
run. No
> user edits, no selects, no nothing.
>
> > Another way to look at this is to ponder whether separating the
tasks into
> > separate transactions is actually serving your intentions. If one
> activity
> > is dependent on being able to "see" the new recversions created
by the
> > other, then both activities surely ought to be in the same
transaction...
>
> No, I don't need them to be separated into different transactions,
only into
> different threads. I'm not interested in the transactions stuff at
all. Only
> to make it work. If there was a way to make IB behave like Paradox
(no
> transactions whatsoever), id do so.
>
> What is the best solution to my problem:
>
> Main Thread:
> ----------------
> 1 connection to system database (sys.gdb)
> 1 connection to production database(prod.gdb)
> - Need to be able to edit data in Prod database, but not while the
thread is
> running.
> - Need to be able to select both from Sys and Prod databases while
thread is
> running.
>
> Worker Thread:
> -----------------
> 1 connection to system database (sys.gdb)
> 1 connection to production database(prod.gdb)
> - Need to be able to select from Sys database while the thread is
running.
> - Need to create & drop tables, indices, procedures in Prod
database.
> (Metadata changes require reconnecting to ensure all changes being
> visible, to my experience)
> - Need to be able to insert/update/delete data (which is the sole
purpose of
> the application) in Prod database.
>
> Worker Thread is created & controlled from Main Thread.
> No data objects are passed between threads.
>
> Any ideas ?
>
> Thanks in advance !
>
> --
> Regards,
>
> Bjørge Sæther
> bjorge@haha_itte.no