After taking advice from several parties, here is my solution (as yet untested, but the theory seems right – unless anyone advises otherwise!!!):
Incorporate the following columns in the table:
LOCK_KEY (UNSIGNED INT up to 4,000,000,000 ish)
LOCK_EXPIRY_TIME (5 minutes into the future).
Depending on your system, you might also add USERNAME so that you know who has got the lock.
When a user wants to edit a row, first check that there isn’t a current active LOCK_EXPIRY_TIME, if the current time is past the expiry time, or there isn’t an expiry time set, then the user can set the lock.
Setting the lock
~~~~~~~~~~~~
Generate a random number or string to use as the LOCK_KEY. This must be retained by the script (php variable $_SESSION[‘lock_key’]) and will be entered into the database shortly.
Get the time and add 5 minutes (or however long you want LOCK_EXPIRY_TIME)
Update the row with the LOCK_KEY and LOCK_EXPIRY_TIME, WHERE id = id_to_update AND there is not a current LOCK_EXPIRY_TIME obtained by another user that was acquired just before we tried to get our lock.
We now have the lock for 5 minutes before it is available to other users.
Updating the row
~~~~~~~~~~~~~
Check that the LOCK_EXPIRY_TIME hasn’t passed and that LOCK_KEY = $_SESSION[‘lock_key’]
Re-take the lock (as above “Setting the lock”) because if it’s 4 minutes and 59 seconds until expiry we may not have enough time to do our UPDATE.
If the expiry time has passed, and the LOCK_KEY in the database is the same our $_SESSION[‘lock_key’] it means that no-one else has tried to lock this row, we can therefore re-acquire the lock with an UPDATE …. WHERE WHERE id = id_to_update AND LOCK_KEY = $_SESSION[‘lock_key’]
Re-check LOCK_KEY to $_SESSION[‘lock_key’] to ensure that no-one acquired the lock just before we attempted to re-take it. If they did display error message.
Once the row has successfully updated, or even as part of the UPDATE, SET LOCK_EXPIRY_TIME to NULL so that other users can edit this row.