Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 9 of 9 total
Thread record changed or deleted by another user...
Mon, Jan 12 2009 1:51 PMPermanent Link

=?iso-8859-1?Q?Santy_Concepci=F3n?=
Hi!

Our app can be configured both as Client/Server and Sharing mode, depending
of customers needs.
Sometimes our customers get an error when trying to save data to the same
table AND the same record at the same time.

The application is a 'Point of Sale' multiuser application, where users
should be able to edit, delete or modify the same record at a time.

After some tests, we noticed the error appears when computer1 and computer2
modify the same record at the same time.

This is a little example of the code that modifies that table
(articulos.dat):

1. Locate the Record
2. Edit record
3. Modify record
4. Post record

The error I get is:
   DBISAM Engine Error # 8708 Record has been changed or deleted by another
user, session, or table cursor in the table 'articulos'

I'm using Pessimistic lock protocol.
Should I use another protocol method instead? Or manual locking or
semaphores?
With pessimistc locking... will LockWaitTime and LockRetryCount properties
improve this?

I would like our app to wait before editing the record until it has been
posted in another machine.
I thought it was made automatically acording to LockRetryCount and
LockWaitTime instead of showing the error message.

Thanks!

Santy
Mon, Jan 12 2009 2:07 PMPermanent Link

Fernando Dias

Team Elevate Team Elevate

Santy,

> I'm using Pessimistic lock protocol.

Are you sure you are getting this error message at the moment you post
the records? Because if you really are using Pessimistic locking, you
should be seeing this message when you try to edit records, not when you
post them.

> Should I use another protocol method instead? Or manual locking or
> semaphores?

No, no and no.
I can explain further after you answer my first question, ok?

--
Fernando Dias
[Team Elevate]
Mon, Jan 12 2009 3:41 PMPermanent Link

=?iso-8859-1?Q?Luis_Concepci=F3n?=
Hi, Fernando...

I'm not sure if the error is raised on Posting or on Edit. I was just
explaining what occurs.

Ok, it seems that the problem appears when trying to EDIT, not on Posting.

Thanks!

"Fernando Dias" <fernandodias.removthis@easygate.com.pt> escribió en el
mensaje de
noticias:77C58F35-168C-472E-A010-FFC0D982791F@news.elevatesoft.com...
> Santy,
>
> > I'm using Pessimistic lock protocol.
>
> Are you sure you are getting this error message at the moment you post the
> records? Because if you really are using Pessimistic locking, you should
> be seeing this message when you try to edit records, not when you post
> them.
>
>> Should I use another protocol method instead? Or manual locking or
>> semaphores?
>
> No, no and no.
> I can explain further after you answer my first question, ok?
>
> --
> Fernando Dias
> [Team Elevate]
Mon, Jan 12 2009 5:02 PMPermanent Link

"Robert"

"Luis Concepción" <direccion@simplygest.es> wrote in message
news:3A99D244-4892-40A7-BE95-AE81EEC441F5@news.elevatesoft.com...
> Hi, Fernando...
>
> I'm not sure if the error is raised on Posting or on Edit. I was just
> explaining what occurs.
>
> Ok, it seems that the problem appears when trying to EDIT, not on Posting.
>

Please read the section on the DBISAM documentation dealing with concurrent
users before you attempt any changes. Changing the lock protocol is not a
smiple issue - there are pros and cons on each one, and  which one you use
depends on the application.

But also how you respond to a 8708 depends on which protocol you use.

The key point to remember is that an 8708 is not an "error". It is a normal
and expected occurence in multiuser systems.

Robert

Mon, Jan 12 2009 6:50 PMPermanent Link

Fernando Dias

Team Elevate Team Elevate

Luis,

> Ok, it seems that the problem appears when trying to EDIT, not on Posting.

As Robert said, 8708 should not be interpreted exactly as an error but
as a warning of an occurrence that you must decide how to deal with.
It  warns you of one of 2 things occured:

- The record you are trying to edit doesn't exist any more - and in that
case the edit action should be aborted.
-The record was changed by another user after it was read from the
database - and in this case a "refresh" followed by a second call to
"edit" may be appropriate (or not - it depends on what you are doing, of
course).

--
Fernando Dias
[Team Elevate]
Tue, Jan 13 2009 2:35 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Luis


Just to add a bit more. What you need is an 8087 eater Smiley In ElevateDB this has been altered and there is a property to tell the engine to eat whatever they became. Each table in the database that might be affected needs a bit of code like that below my sig as the OnEditError event.


Roy Lambert [Team Elevate]


procedure TDM.EditError(DataSet: TDataSet; E: EDatabaseError; var Action: TDataAction);
var
ID1, ID2: TBookmark;
begin
if (E is EDBISAMEngineError)
 and (EDBISAMEngineError(E).ErrorCode = DBISAM_KEYORRECDELETED)
 and (not TDBISAMTable(DataSet).RecordIsLocked) then begin
 ID1 := DataSet.GetBookmark;
 DataSet.Refresh;
 ID2 := DataSet.GetBookmark;
 if DataSet.CompareBookmarks(ID1, ID2) = 0 then Action := daRetry else begin
  MessageDlg('That record has been deleted or its ID changed', mtError, [mbOK], 0);
  Action := daAbort;
 end;
 DataSet.FreeBookmark(ID1);
 DataSet.FreeBookmark(ID2);
end else begin
 MessageDlg(E.Message, mtError, [mbOK], 0);
 Action := daAbort;
end;
end;
Tue, Jan 13 2009 4:54 AMPermanent Link

=?iso-8859-1?Q?Santy_Concepci=F3n?=
Thanks, Roy...

I think your code example is the better way to solve this.

It is a POS applications, so message alerts are not suppoused to be shown
when this happens.

The problem is that the new data have to be posted neccessary, because there
are other related tables affected in that operation that have been already
posted.

I have modified LockWaitTime to an upper value and tried your code. Now it
works fine and the warning never appears.

I will explain what my application does exactly:


TableA stores sales records:
   NUMBER        DATE                TOTAL
       1                2009-01-02         10.90
       2                2009-01-05         40.20

TableB stores detailed sales:
   NUMBER        ITEM        PRICE        QUANTITY
       1                1A122B        10.90            1
       2                1AB                30.00           1
       2                1BJJK            10.20           1

TableC stores the Items:
       ITEM            NAME        PRICE    QUANTITY
       1A122B     Item 1            10.90        100
       1AB            Item 2            30.00        58
       1BJJK        Item 3            10.20        29



So, I first Post TableA. This operation never gives the warning because they
are always new records (with append, not edit).

Then, if TableA was posted correctly, I post TableB (also with Append). No
errors here.

The problem becomes when trying to Edit TableC, containing the Items, and I
have to update its quantity.
If the same item has been changed by another machine or user, I HAVE to
refresh the data and then POST the new quantity, so I think the OnEditError
event is the better method.

Am I wrong?

Thanks everybody!


--
Santy C


"Roy Lambert" <roy.lambert@skynet.co.uk> escribió en el mensaje de
noticias:CEE2E5F8-E76A-4AD9-9A13-3B1C5E34EEFD@news.elevatesoft.com...
> Luis
>
>
> Just to add a bit more. What you need is an 8087 eater Smiley In ElevateDB
> this has been altered and there is a property to tell the engine to eat
> whatever they became. Each table in the database that might be affected
> needs a bit of code like that below my sig as the OnEditError event.
>
>
> Roy Lambert [Team Elevate]
>
>
> procedure TDM.EditError(DataSet: TDataSet; E: EDatabaseError; var Action:
> TDataAction);
> var
> ID1, ID2: TBookmark;
> begin
> if (E is EDBISAMEngineError)
>   and (EDBISAMEngineError(E).ErrorCode = DBISAM_KEYORRECDELETED)
>   and (not TDBISAMTable(DataSet).RecordIsLocked) then begin
>   ID1 := DataSet.GetBookmark;
>   DataSet.Refresh;
>   ID2 := DataSet.GetBookmark;
>   if DataSet.CompareBookmarks(ID1, ID2) = 0 then Action := daRetry else
> begin
>    MessageDlg('That record has been deleted or its ID changed', mtError,
> [mbOK], 0);
>    Action := daAbort;
>   end;
>   DataSet.FreeBookmark(ID1);
>   DataSet.FreeBookmark(ID2);
> end else begin
>   MessageDlg(E.Message, mtError, [mbOK], 0);
>   Action := daAbort;
> end;
> end;
Tue, Jan 13 2009 12:37 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Santy,

<< so I think the OnEditError event is the better method.

Am I wrong? >>

No, you are 100% correct.  Using an OnEditError handler will ensure that you
will always see the most recent version of the record for your quantity
update, and without any 8708 warning message bubbling up so that the user
sees it.

--
Tim Young
Elevate Software
www.elevatesoft.com

Tue, Jan 13 2009 12:45 PMPermanent Link

=?iso-8859-1?Q?Santy_Concepci=F3n?=
Thanks, Tim...

I have been testing it and it seems it works fine.

Thanks!

--
Santy

"Tim Young [Elevate Software]" <timyoung@elevatesoft.com> escribió en el
mensaje de
noticias:1A463843-B030-42B3-97C3-048C9A774911@news.elevatesoft.com...
> Santy,
>
> << so I think the OnEditError event is the better method.
>
> Am I wrong? >>
>
> No, you are 100% correct.  Using an OnEditError handler will ensure that
> you will always see the most recent version of the record for your
> quantity update, and without any 8708 warning message bubbling up so that
> the user sees it.
>
> --
> Tim Young
> Elevate Software
> www.elevatesoft.com
>
>
Image