Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 21 total
Thread Transactions
Tue, May 2 2006 3:36 AMPermanent Link

"Godfrey"
Hi All

DBISAM V4.23

I am working with a local database and transactions. When I save a record
the posting
is done within a transaction.  If the operator reuses a code that is
already in the database,
it results in a duplicate record error(which is understandable).

What I cannot understand is:

Why does the transaction still commit the record if an error occurs when
posting.
Should the transaction not fail and rollback the posting of the record?

After posting, the duplicate error keeps popping up, if the user tries to
continue using the form.
The only way to stop it is to either delete the duplicate record (which to
my mind
should never have been posted by the transaction) or exit and restart the
program.

I have tried putting code in the onposterror event but it does not help
much, only
gives you a nicer error message.

Can someone assist me on this one.  Below is the code I use to post the
record.

Thanks
Godfrey


var
TableListGlobal : TStrings;
begin
if MessageDlg('Save?',
   mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then
 begin
  if EditLName.Text <> '' then
  begin
   TableListGlobal := TStringList.Create;
   try
   TableListGlobal.Add('Customer');
   DataModule1.Global.StartTransaction(TableListGlobal);
   try
   if Newitem = True then
   begin
    DataModule1.TabCustomer.Append;
    SaveFields;
    DataModule1.TabCustomer.Post;
    Newitem := False;
   end
   else
   begin
    DataModule1.TabCustomer.Edit;
    SaveFields;
    DataModule1.TabCustomer.Post;
   end;
   DataModule1.Global.Commit(True);
   except
   if DataModule1.Global.InTransaction then
   DataModule1.Global.Rollback;
   end;
  finally
  TableListGlobal.Free;
  end;
  end
  else
  ShowMessage('No Name');
 end;
end;

Tue, May 2 2006 4:46 AMPermanent Link

"Hannes Danzl[NDD]"
> Can someone assist me on this one.  Below is the code I use to post the
> record.

The logic is the same for every database:

StartTransaction
try
 Edit
 try
   // do your stuff
   Post;
 except
   Cancel;
   raise;
 end;
 Commit;
except
 Rollback;
end;


OR

use a local var to signal an error. NEVER EVER use transactions without try
except. An exception leaves them open, thus you're building up nested
transaction environments on the server which means lots of resources used and
potentially thousands of locked records until it times out and is rolled back
by the server, runs out of resources... or worse you commit inner transactions
nicely and on closedown the outermost one is auto rolled back -> you think all
was fine while actually all nested transactions are getting rolled back!

--

Hannes Danzl
Newsgroup archive at http://www.tamaracka.com/search.htm
Tue, May 2 2006 7:36 AMPermanent Link

"Robert"

"Godfrey" <none> wrote in message
news:2B0875D4-349B-4405-BCD4-8AD44C7CC1E3@news.elevatesoft.com...
> Should the transaction not fail and rollback the posting of the record?
>

Rollback does not cancel pending edits. Thus, when you scroll, etc, your
pending edits might en up getting posted anyway. I use this it seems to
solve the problem.

procedure TDM.MyRollback;
var i : integer;
begin
  MyDatabase.Rollback;
  for i := 0 to self.ComponentCount - 1 do
   if self.Components[i] is tdBIsamTable then
     with self.Components[i] as tDBISAMTable do
       if state <> dsbrowse then  begin
         Cancel;
       end;
end;

I'm sure there's more efficient ways to code this, but in my case rollbacks
are infrequent so it does not matter.

Robert

Tue, May 2 2006 1:54 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Godfrey,

<< What I cannot understand is:

Why does the transaction still commit the record if an error occurs when
posting. Should the transaction not fail and rollback the posting of the
record? >>

The Posting of a record is not the same as the committing of a transaction.
Posting is handled by the base TDataSet component and is separate from the
actual DBISAM engine itself, so when a rollback occurs, any edits that are
currently in progress stay in progress and don't change.  What you need is
what Hannes indicated - a try..except with a Cancel call if there's an error
during the Posting inside of the try..except for the transaction itself.

--
Tim Young
Elevate Software
www.elevatesoft.com

Tue, May 2 2006 5:09 PMPermanent Link

"Hannes Danzl[NDD]"
Robert wrote:

>
> "Godfrey" <none> wrote in message
> news:2B0875D4-349B-4405-BCD4-8AD44C7CC1E3@news.elevatesoft.com...
> > Should the transaction not fail and rollback the posting of the record?
> >
>
> Rollback does not cancel pending edits. Thus, when you scroll, etc, your
> pending edits might en up getting posted anyway. I use this it seems to
> solve the problem.
>
> procedure TDM.MyRollback;
> var i : integer;
> begin
>   MyDatabase.Rollback;
>   for i := 0 to self.ComponentCount - 1 do
>    if self.Components[i] is tdBIsamTable then
>      with self.Components[i] as tDBISAMTable do
>        if state <> dsbrowse then  begin
>          Cancel;
>        end;
> end;

Hm. I've no idea right now how DBIsam is implemented, but doing the Cancel
AFTER the rollback might create trouble. A rollback would certainly have to
cancel any pending updates on the *server* side, so you might end up with some
messup in the states of the tables.

--

Hannes Danzl [NexusDB Developer]
Newsgroup archive at http://www.tamaracka.com/search.htm
Tue, May 2 2006 5:33 PMPermanent Link

"Robert"

"Hannes Danzl[NDD]" <hannes@nexusdb.dbnexus.com> wrote in message
news:xn0els8vt52l35c00f@news.elevatesoft.com...
> Robert wrote:
>
>>
>> "Godfrey" <none> wrote in message
>> news:2B0875D4-349B-4405-BCD4-8AD44C7CC1E3@news.elevatesoft.com...
>> > Should the transaction not fail and rollback the posting of the record?
>> >
>>
>> Rollback does not cancel pending edits. Thus, when you scroll, etc, your
>> pending edits might en up getting posted anyway. I use this it seems to
>> solve the problem.
>>
>> procedure TDM.MyRollback;
>> var i : integer;
>> begin
>>   MyDatabase.Rollback;
>>   for i := 0 to self.ComponentCount - 1 do
>>    if self.Components[i] is tdBIsamTable then
>>      with self.Components[i] as tDBISAMTable do
>>        if state <> dsbrowse then  begin
>>          Cancel;
>>        end;
>> end;
>
> Hm. I've no idea right now how DBIsam is implemented, but doing the Cancel
> AFTER the rollback might create trouble. A rollback would certainly have
> to
> cancel any pending updates on the *server* side, so you might end up with
> some
> messup in the states of the tables.
>

See Tim's posting in this thread. Also, if the rollback cancels the updates,
the table state would be dsbrowse, so no harm done. But it seems that it
should work the same doing the rollback at the end. The point is that you
could have several tables in an edit state when you rollback a transaction,
not just the one that caused the exception.

Of course, if "A rollback would certainly have to cancel any pending
update[S]" then the whole issue becomes academic. In fact, many developers
assume exactly that: that if you have something like

starttransaction;
table1.edit;
changes to table1.
table2.edit;
changes to table2;
rollback;

the changes to both tables are wiped out. Not so, in DBISAM. So any action
(such as scrolling on a grid) that causes an automatic post, will cause you
to end up with unwanted changes to your database.

Robert

Tue, May 2 2006 5:40 PMPermanent Link

"Hannes Danzl[NDD]"
> the changes to both tables are wiped out. Not so, in DBISAM. So any action
> (such as scrolling on a grid) that causes an automatic post, will cause you
> to end up with unwanted changes to your database.

neither in most others. the rollback is a server side action, and the server
doesn't know anything about the open edit state on the client side. That's the
reason why i would always cancel pending edit/inserts BEFORE i rollback a
transaction.

--

Hannes Danzl [NexusDB Developer]
Newsgroup archive at http://www.tamaracka.com/search.htm
Tue, May 2 2006 5:49 PMPermanent Link

"Robert"

"Hannes Danzl[NDD]" <hannes@nexusdb.dbnexus.com> wrote in message
news:xn0els9n653on8i00k@news.elevatesoft.com...
>> the changes to both tables are wiped out. Not so, in DBISAM. So any
>> action
>> (such as scrolling on a grid) that causes an automatic post, will cause
>> you
>> to end up with unwanted changes to your database.
>
> neither in most others. the rollback is a server side action, and the
> server
> doesn't know anything about the open edit state on the client side.

So why then did you write that "A rollback would certainly have to cancel
any pending updates"? Plus the OP had indicated that he was using a local
database.

That's the
> reason why i would always cancel pending edit/inserts BEFORE i rollback a
> transaction.
>

I don't see where it makes any diference. But is seems, in some way that I
can not prove, that moving the rollback to AFTER the loop would be safer,
since the cancels would be inside the transaction.

Robert

Tue, May 2 2006 6:08 PMPermanent Link

"Hannes Danzl[NDD]"
> So why then did you write that "A rollback would certainly have to cancel
> any pending updates"? Plus the OP had indicated that he was using a local
> database.

The edits set locks server side, which would be rolled back with the
transaction. Sorry I wasn't clear.

> I don't see where it makes any diference. But is seems, in some way that I
> can not prove, that moving the rollback to AFTER the loop would be safer,
> since the cancels would be inside the transaction.

For some databases a rollback on the server side doesn't necessarily mean that
the client side (vcl) components get their states synched.

--

Hannes Danzl [NexusDB Developer]
Newsgroup archive at http://www.tamaracka.com/search.htm
Wed, May 3 2006 10:08 AMPermanent Link

"Godfrey"
Thanks Everybody

I am just battling a bit with the syntacs.

Can someone assist me with the code to trap a duplicate key, which will go
in the
except section, if an error occurs during the post .  I cannot seem to get
it right.





"Tim Young [Elevate Software]" <timyoung@elevatesoft.com> wrote in message
news:7B883598-E162-48C1-A2B3-0070A3ADED40@news.elevatesoft.com...
> Godfrey,
>
> << What I cannot understand is:
>
> Why does the transaction still commit the record if an error occurs when
> posting. Should the transaction not fail and rollback the posting of the
> record? >>
>
> The Posting of a record is not the same as the committing of a
> transaction. Posting is handled by the base TDataSet component and is
> separate from the actual DBISAM engine itself, so when a rollback occurs,
> any edits that are currently in progress stay in progress and don't
> change.  What you need is what Hannes indicated - a try..except with a
> Cancel call if there's an error during the Posting inside of the
> try..except for the transaction itself.
>
> --
> Tim Young
> Elevate Software
> www.elevatesoft.com
>
>

Page 1 of 3Next Page »
Jump to Page:  1 2 3
Image