* This is used when you need to execute a series of command on a table that requires a lock * We use a secondary table to lock at a record level * expC1 Alias FUNCTION LockTable PARAMETER tcAlias LOCAL lnOldSel,lnCompteur lnOldSel=SELECT() lnCompteur=0 SELECT Lock SEEK UPPER(tcAlias) ORDER TAG Table DO WHILE (NOT RLOCK()) AND (INKEY(0.1)=0) AND lnCompteur<=25 lnCompteur=lnCompteur+1 ENDDO SELECT(lnOldSel) * This is used when you need to execute a series of command on a table that requires a lock * We use a secondary table to lock at a record level * expC1 Alias FUNCTION UnlockTable PARAMETER tcAlias LOCAL lnOldSel lnOldSel=SELECT() SELECT Lock SEEK UPPER(tcAlias) ORDER TAG Table UNLOCK SELECT(lnOldSel)Then, wherever I have some code that requires a lock, I can then do something like this:
* Only add the message view log if this user didn't read this message before IF gnMember<>NoMember LockTable('MessLog') SELECT MessLog LOCATE FOR AddUser=gnMember AND NoThread=tnNoThread IF NOT FOUND() AddNew() REPLACE NoThread WITH tnNoThread ENDIF UnlockTable('MessLog') SELECT Thread ENDIFSo, this doesn't require candidate key, thus no problem would occur about a uniquess of violation. It also doesn't touch the main table as we use a secondary table, Lock.dbf, just for that purpose.