Share via


Managing Conflicts When Updating Data

Whether you choose buffering, transactions, or views, you must manage conflicts during the update process. Managing conflicts encountered in multiuser environments can require extensive and repetitive code. A complete conflict management routine performs the following:

  • Detects a conflict.

  • Identifies the nature and location of the conflict.

  • Provides enough information so that the user can intelligently resolve the conflict.

For an example of a conflict management routine, see the data checker class in Samples.vcx, located in the Visual FoxPro ...\Samples\Classes directory. Just add the class to a form and call the CheckConflicts method before any operation that writes buffered data to the table, for example moving the record pointer if you're using row buffering, closing a table, or issuing TABLEUPDATE( ).

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 multiuser 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 multiuser 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

Reference

SET REPROCESS Command

ON ERROR Command

RETRY Command

Other Resources

Updating Data

Programming for Shared Access