 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Mark Reichert Guest
|
Posted: Fri Feb 23, 2007 12:00 am Post subject: InTransaction, StartTransaction and Double Duty Code |
|
|
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
|
Posted: Fri Feb 23, 2007 1:10 am Post subject: Re: InTransaction, StartTransaction and Double Duty Code |
|
|
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
|
Posted: Fri Feb 23, 2007 1:13 am Post subject: Re: InTransaction, StartTransaction and Double Duty Code |
|
|
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
|
Posted: Fri Feb 23, 2007 5:06 am Post subject: Re: InTransaction, StartTransaction and Double Duty Code |
|
|
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
|
Posted: Sat Feb 24, 2007 12:34 am Post subject: Re: InTransaction, StartTransaction and Double Duty Code |
|
|
Why not use two separate transactions?
Your description sounds like these are different things.
--
Patrick Moloney |
|
| Back to top |
|
 |
Mark Reichert Guest
|
Posted: Sat Feb 24, 2007 2:00 am Post subject: Re: InTransaction, StartTransaction and Double Duty Code |
|
|
"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 |
|
 |
|
|
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
|
|