BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

InTransaction, StartTransaction and Double Duty Code

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Databases (InterBase Express)
View previous topic :: View next topic  
Author Message
Mark Reichert
Guest





PostPosted: Fri Feb 23, 2007 12:00 am    Post subject: InTransaction, StartTransaction and Double Duty Code Reply with quote



I ran into trouble with code that was both used in a larger pull of data
under a single StartTransaction-Commit block and standalone to get a single
value. I fixed it by putting in the TransactionNeeded flag based on what I
could swear was a post here in January but I can't find a trace of it now.
My actual code is not exactly the code below but much like it.

Does anybody see any problems in using a TransactionNeeded flag for any code
that might both be called with a Transaction in progress AND by itself when
a Transaction is not in progress? The examples I've seen with just using
InTransaction would end up committing the Transaction in progress
prematurely. Of course if one put in InTransaction and StartTransaction
everywhere the problem would resolve itself by having many sequential
transactions.

function GetName(NameID: Integer) : String;
Var TransactionNeeded : Boolean;
begin
With ibsql1 do
begin
With Transaction do begin
TransactionNeeded := Not InTransaction;
If TransactionNeeded Then
StartTransaction;
end;
Try
ParamByName('NAMEID').AsInteger := NameID;
ExecQuery;

If not Eof Then
Result := FieldByName('NAME').AsString;
Close;
Finally
If TransactionNeeded Then
Transaction.Commit;
End;
end;
end;
Back to top
Bill Todd
Guest





PostPosted: Fri Feb 23, 2007 1:10 am    Post subject: Re: InTransaction, StartTransaction and Double Duty Code Reply with quote



Mark Reichert wrote:

Quote:
I ran into trouble with code that was both used in a larger pull of
data under a single StartTransaction-Commit block and standalone to
get a single value. I fixed it by putting in the TransactionNeeded
flag based on what I could swear was a post here in January but I
can't find a trace of it now. My actual code is not exactly the code
below but much like it.

Does anybody see any problems in using a TransactionNeeded flag for
any code that might both be called with a Transaction in progress AND
by itself when a Transaction is not in progress? The examples I've
seen with just using InTransaction would end up committing the
Transaction in progress prematurely. Of course if one put in
InTransaction and StartTransaction everywhere the problem would
resolve itself by having many sequential transactions.

function GetName(NameID: Integer) : String;
Var TransactionNeeded : Boolean;
begin
With ibsql1 do
begin
With Transaction do begin
TransactionNeeded := Not InTransaction;
If TransactionNeeded Then
StartTransaction;
end;
Try
ParamByName('NAMEID').AsInteger := NameID;
ExecQuery;

If not Eof Then
Result := FieldByName('NAME').AsString;
Close;
Finally
If TransactionNeeded Then
Transaction.Commit;
End;
end;
end;

No, there is nothing wrong with what you are doing. InTransaction will
not work because it does not tell you where the transaction was
started. To know that you need the TransactionNeeded variable.

--
Bill Todd (TeamB)
Back to top
Wayne Niddery [TeamB]
Guest





PostPosted: Fri Feb 23, 2007 1:13 am    Post subject: Re: InTransaction, StartTransaction and Double Duty Code Reply with quote



Mark Reichert wrote:
Quote:

Does anybody see any problems in using a TransactionNeeded flag for
any code that might both be called with a Transaction in progress AND
by itself when a Transaction is not in progress?

Your code example looks fine.

--
Wayne Niddery - Winwright, Inc (www.winwright.ca)
"Nature abhors the vacuum tube." - J.R. Pierce, Bell Labs engineer who
coined the term 'transistor'
Back to top
ssamayoa
Guest





PostPosted: Fri Feb 23, 2007 5:06 am    Post subject: Re: InTransaction, StartTransaction and Double Duty Code Reply with quote

I use Active property:

TransActiva := Transaction.Active;
if not TransActiva then
Transaction.StartTransaction;
try
...
if not TransActiva then
Transaction.Commit;
except
on E: Exception do
begin
if not TransActiva then
Transaction.RollBack;
raise;
end;
end;



--- posted by geoForum on http://delphi.newswhat.com
Back to top
Patrick Moloney
Guest





PostPosted: Sat Feb 24, 2007 12:34 am    Post subject: Re: InTransaction, StartTransaction and Double Duty Code Reply with quote

Why not use two separate transactions?
Your description sounds like these are different things.


--
Patrick Moloney
Back to top
Mark Reichert
Guest





PostPosted: Sat Feb 24, 2007 2:00 am    Post subject: Re: InTransaction, StartTransaction and Double Duty Code Reply with quote

"Patrick Moloney" <NewsID*at*SandrockSoftware.c*o*m> wrote in message
news:45df339b$1 (AT) newsgroups (DOT) borland.com...
Quote:
Why not use two separate transactions?
Your description sounds like these are different things.

Code reuse.

I left a few things out period, on top of deleting one too many things in my
effort to change the code so that it exactly illustrates the problem but
doesn't reveal the actual code (This a Googleable newsgroup after all). I
got the answer I wanted, but left you wondering how I'm using that code.

First, in the post that started the thread, changing two lines make it more
like my actual code:

procedure TDM.ReadMemo(MemoID: Integer; TheMemo: TMemoryStream);

and

If not EOF Then
SaveBlobToStream(FieldByName('MEMO'), TheMemo);

(Where SaveBlobToStream has the standard code that should surround a
TIBXSQLVAR.SaveToStream)

Which is called from

procedure TDM.SetMemoID(const Value: Integer);
begin
FMemoID := Value;
ReadMemo(FMemoID, FMemoStream)
end;
MemoStream is a property of TDM.

And then there is another method

function TDM.ReadRecord(RecordID : String) : Boolean;
begin
With ibsqlReadRecord do
begin
Transaction.StartTransaction;
Try
ParamByName('ID').AsString := RecordID;
ExecQuery;
If not Eof Then
begin
MemoID := FieldByName('MEMOID').AsString
TheTime := FieldByName('TIME').AsTime;
end;
Close;
Result := True;
Finally
Transaction.Commit;
End;
end;
end;

After which the code calling ReadRecord can, if it returned true, get MemoID
and TheTime and get the memo by

FAnotherMemoStream.Clear;
FAnotherMemoStream.LoadFromStream(MemoStream);

But in entirely different section of code, I use

DM.ReadMemo(MemoID, MemoStream);

To just get the Memo without the other stuff.

So while ReadRecord will only be called stand alone while no transaction
should already be running, ReadMemo can be called in both situations and
needs to handle either.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Databases (InterBase Express) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.