Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Cannot RLock()
Message
De
07/06/2002 13:34:13
 
 
Information générale
Forum:
Visual FoxPro
Catégorie:
Base de données, Tables, Vues, Index et syntaxe SQL
Titre:
Divers
Thread ID:
00665258
Message ID:
00666077
Vues:
18
Hi Evelyn.

>I am worried that if two or more users can grab the same record at the same time, since only one of them will be able to save first, someone's change could be overwritten by the other user. Depending on who gets to save his work first, the counts would come up short.

Let's say two users access the same record at the same time, and the summary count for both is 5. Then User A adds 1 to the count (so it's 6) and saves. User B (who still sees 5) adds 2 to the count (so it's 7, but really it should be 8, given User A's change) and saves. What happens next is that for User B, the TABLEUPDATE() function fails and if you use AERROR() to check what went wrong, you'll find error 1585 occurred, meaning that the user tried to change a record that another user changed.

Different applications can handle this in different ways, but one way you might handle this is to use spin through all the fields in the current record and use a combination of the value this user has, the original value before they changed it (OLDVAL()), and the current value as it is on disk (accounting for changes other users made, CURVAL()). Here's the overall logic:
lnFields = afields(laFields)
for lnI = 1 to lnFields
  lcField      = laFields[lnI]
  luOldVal     = oldval(lcField)
  luCurVal     = curval(lcField)
  luValue      = evaluate(lcField)
  llOtherUser  = luOldVal <> luCurVal
  llThisUser   = luValue  <> luOldVal
  llSameChange = luValue  == luCurVal
  do case

* The other user edited this field but this user didn't, so grab the new
* value.

    case llOtherUser and not llThisUser
      replace (lcField) with luCurVal

* The other user didn't edit this field, or they both made the same change,
* so we don't need to do anything.

    case not llOtherUser or llSameChange

* Uh-oh, both users changed this field, but to different values, so we have a
* "real" conflict. In the case of the SummaryCount field, we'll handle it by
* applying changes both users made. For any other field, flag that we have
* a conflict.

    case lcField = 'SUMMARYCOUNT'
      lnOtherUserChange = luCurVal - luOldVal
      lnThisUserChange  = luValue  - luOldVal
      replace (lcField) with luOldVal + luOtherUserChange + ;
        luThisUserChange
        
    otherwise
      llConflict = .T.
  endcase
next

* If we don't have a "real" conflict, force all the changes.

if not llConflict
  llSuccess = tableupdate(2, .T.)
else
*** handle a "real" conflict in some way eg. ask the user what to do
endif
By using the REPLACE command to force this user's record to contain the values we want, and then forcing the update (the .T. parameter in TABLEUPDATE()), changes both users made to the SummaryCount field are handled.

Hope this helps.

Doug
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform