Management of Conflicts

Whether you choose buffering, transactions, or views, you must manage conflicts during the update process.

Managing Buffering Conflicts

You can make data update operations more efficient by carefully choosing how and when to open, buffer, and lock data in a multi-user environment. You should limit the time a record or table is subject to access conflicts. Still, you must anticipate and manage the inevitable conflicts that result. A conflict occurs when one user tries to lock a record or table that's currently locked by another user. Two users cannot lock the same record or table at the same time.

Your application should contain a routine to manage these conflicts. If your application doesn't have a conflict routine, the system can lock up. A deadlock occurs when one user has locked a record or a table and tries to lock another record that's locked by a second user who, in turn, is trying to lock the record that's locked by the first user. While such occurrences are rare, the longer that a record or table is locked, the greater the chance of deadlock.

Trapping Errors

Designing a multi-user application or adding network support to a single-user system requires that you deal with collisions and trap for errors. Using Visual FoxPro record and table buffers simplifies some of this work.

If you attempt to lock a record or table already locked by another user, Visual FoxPro returns an error message. You can use SET REPROCESS to automatically deal with unsuccessful lock attempts. This command, in combination with an ON ERROR routine and the RETRY command, enables you to continue or cancel the lock attempts.

The following example demonstrates automatic reprocessing of a failed operation, using SET REPROCESS.

Using SET REPROCESS and ON ERROR to Manage User Collisions

Code Comment
ON ERROR DO err_fix WITH ERROR(),MESSAGE()
SET EXCLUSIVE OFF   
SET REPROCESS TO AUTOMATIC
USE customer
IF !FILE('cus_copy.dbf')
   COPY TO cus_copy
ENDIF
This routine runs if an error occurs.
Open the files non-exclusively.
Reprocessing of unsuccessful locks is automatic.
Open the table.

Create the APPEND FROM table if needed.
DO app_blank
DO rep_next
DO rep_all
DO rep_curr
DO add_recs
The main routine starts here.
These commands are examples of codes that could be executed in the course of your program.
ON ERROR
The main routine ends here.
PROCEDURE app_blank      
   APPEND BLANK
RETURN
ENDPROC
Routine to append a blank record.
PROCEDURE rep_next
   REPLACE NEXT 1 contact WITH ;
      PROPER(contact)
RETURN
ENDPROC
Routine to replace data in the current record.
PROCEDURE rep_all      
   REPLACE ALL contact WITH ;
      PROPER(contact)
   GO TOP
RETURN
ENDPROC
Routine to replace data in all records.
PROCEDURE rep_curr      
   REPLACE contact WITH PROPER(contact)
RETURN
ENDPROC
Routine to replace data in the current record.
PROCEDURE add_recs      
   APPEND FROM cus_copy
RETURN
ENDPROC
Routine to append records from another file.

The following example demonstrates an error procedure that starts when the user presses ESC.

Error Handling Using the ESC Key

Code Comment
PROCEDURE err_fix
   PARAMETERS errnum, msg
This program is called when an error is encountered and the user escapes from the wait process.
DO CASE
Figure out what kind of error this is.
Is it "File is in use by another"?
   CASE errnum = 108      
      line1 = "File cannot be locked."
      line2 = "Try again later..."
 
   CASE errnum = 109 .OR. errnum = 130
      line1 = "Record cannot be locked."
      line2 = "Try again later."
Or "Record is in use by another"?
   OTHERWISE            
      line1 = msg + " "
      line2 = ;
         "See your system administrator."
ENDCASE
Or is it unknown?


=MESSAGEBOX( line1 + line2, 48, "Error!" )
RETURN                  
Display the error message in a dialog box with an exclamation point and an OK button.

See Also

Management of Updates with Views | Detecting and Resolving Conflicts | Programming for Shared Access | SET REPROCESS | ON ERROR | RETRY