Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 8 of 8 total
Thread OnPostError handler
Tue, Jul 16 2013 5:44 AMPermanent Link

Paul Ralphs

Fixzone UK Ltd

Avatar

Hi there,

we have an issue where we are getting the 'this record has been edited or deleted by another user' when the record is attempted to be posted.  This is generally because an auto-ops task has run & has indeed changed a flag on the record in question.

My question is if anyone has a suggestion of how best we can handle this situation without the end-user losing their changes (this is the current situation).  Basically we are looking to reconcile the posting error, much as you can with ClientDataSet for example...

FYI - we are using Optimistic locking and so are getting this condition in the OnPostError handle for TDBISAMTable  

I thought somebody has probably handled this issue before (possibly in the OnBeforePost etc?)... any suggestions would be really helpful & gratefully received

Many Thanks
Tue, Jul 16 2013 6:43 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Paul


This is the handler I used to manage the infamous 8708 error. I've been using ElevateDB for a while and I can't remember just how well this works.

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;

If you're operating with a filter and the filter excludes the record I'm not sure what will happen. If the worst comes to the worst you can always use a canned query to do the editing and post back changes programmatically.

The other option  is a timer which periodically refreshes the table. The problem with that is if there are pending edits they'll be flushed.

Roy Lambert [Team Elevate]
Wed, Jul 17 2013 9:37 AMPermanent Link

Paul Ralphs

Fixzone UK Ltd

Avatar

Hi Roy

Thanks for the response... however the OnEditError is not being triggered, it is OnPostError ... I think this is because we are using Optimistic and not  Pessimistic locking.

We have a process that sends information to PDAs ... and this is currently controlled by a 'sync' flag on this record (this is in process of redesign but as it will take a while to change all the application that would be affected as they have this current logic) ; the problem is that when the transfer process runs it flicks this flag False-->True..   

This is the only field that has been changed ... but the end-user gets the error and cannot save their work.  So I was looking to see if there was a simple option.. where I could put in a check to see if this is the only field that is affected... if so override the post error.

I thought I would just see if anyone else had done anything to handle this type of thing....
Wed, Jul 17 2013 11:11 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Paul

>Thanks for the response... however the OnEditError is not being triggered, it is OnPostError ... I think this is because we are using Optimistic and not Pessimistic locking.
>
>We have a process that sends information to PDAs ... and this is currently controlled by a 'sync' flag on this record (this is in process of redesign but as it will take a while to change all the application that would be affected as they have this current logic) ; the problem is that when the transfer process runs it flicks this flag False-->True..
>
>This is the only field that has been changed ... but the end-user gets the error and cannot save their work. So I was looking to see if there was a simple option.. where I could put in a check to see if this is the only field that is affected... if so override the post error.
>
>I thought I would just see if anyone else had done anything to handle this type of thing....

As usual I can't visualise sufficiently what you are doing. The only thing I can think of is you might be able to do something in the OnBeforePost event but I can't quite picture what Frown

Your best bet is contacting support and opening a ticket with Tim he at least understands these things, or so we all hope Smiley

Roy Lambert [Team Elevate]
Wed, Jul 17 2013 11:33 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Paul


Having posted I opened up my trusty copy of D6 and had a look. Try the OnPostError. In outline:

Firstly test the exception, if its 8708 then
1. capture the content of the fields
2. refresh the table
3. put the content of the fields back
4. set Action to daRetry


No idea if its going to work or not because I've never used it but its worth a try.

This is the info from the manual as of v4.26

This event is triggered when an error occurs during a call to the
TDBISAMTable or TDBISAMQuery Post method. The usual cause of
an error is a key violation for a unique index or the violation of a
table constraint, however it can also be triggered by a record lock
failure if the locking protocol for the current session is set to
optimistic. Please see the Updating Tables and the Locking and
Concurrency topics for more information on using this event and the
DBISAM locking protocols.

Roy Lambert [Team Elevate]
Sun, Jul 21 2013 2:58 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Paul,

<< we have an issue where we are getting the 'this record has been edited or
deleted by another user' when the record is attempted to be posted.  This is
generally because an auto-ops task has run & has indeed changed a flag on
the record in question.

My question is if anyone has a suggestion of how best we can handle this
situation without the end-user losing their changes (this is the current
situation).  Basically we are looking to reconcile the posting error, much
as you can with ClientDataSet for example...

FYI - we are using Optimistic locking and so are getting this condition in
the OnPostError handle for TDBISAMTable >>

Unfortunately there's no way to deal with this from within the OnPostError
handler itself.  You'll have to set a flag, abort the operation by setting
the Action parameter to daAbort, call the Refresh method, Edit the record
again, re-apply the updates, clear the flag, and then re-post.  Of course,
it's possible that you could encounter the same problem again, so the flag
clearing is important. Smile

Something like this should work:

UpdateSuccessful:=False;
while (not UpdateSuccessful) do
  begin
  UpdateSuccessful:=True;
  // Update record values
  Post;
  if (not UpdateSuccessful) then
     begin
     Refresh;
     Edit;
     // Update record values
     end;
  end;

If you have any other questions, please let me know.

Tim Young
Elevate Software
www.elevatesoft.com
Thu, Jul 25 2013 11:44 AMPermanent Link

Paul Ralphs

Fixzone UK Ltd

Avatar

Hi Time, Thanks for that  Smile
Thu, Jul 25 2013 11:45 AMPermanent Link

Paul Ralphs

Fixzone UK Ltd

Avatar

Thanks Tim !
Image