I have begun writing a website using Membase (php memcached library) and I've come up against a conceptual wall. This is my scenario:
I have some data that is stored in a key-value pair which will be accessed and modified by more than one user. If one of these users wants to update the data then they:
1. Get the data and also get the CAS token. 2. Attempt to do a CAS write. 3. If the CAS write fails, start again from 1. 4. If the CAS write succeeds, move on.
What if I have two users trying to access the same piece of data? Thinking about this I can see that it is going to result in an infinite loop:
1. User 1 gets the data and also retrieves CAS token z1. 2. User 2 then gets the same data and now retrieves CAS token z2. 3. User 1 attempts to do a CAS write but it fails since z1 != z2 4. User 1 repeats step 1 and step 3 with user1's CAS tokens incrementing to z3, z5, z7, etc. 5. User 2 attempts to do a CAS write but it fails since z2 != z3. 6. User 2 repeats step 2 and step 5 with user 2's CAS tokens incrementing to z4, z6, z8, etc.
I know such a scenario is probably really uncommon since two users would have to try and modify the same piece of data at the same instant, but "uncommon" != "never".
In order to prevent this scenario I thought of introducing a random delay into the process so that steps 1-6 happen out of order and are therefore able to complete. However, I don't like this idea because it will slow the website down.
Is there a standard way of handling this type of problem?
I can give more info on the specific data I want to update if that helps, but this seems like a scenario I am likely to encounter quite a bit so I want to keep it general. One thing I will say though is that the process happens unbeknownst to both users - i.e. it is their browsers which are performing the updates, the action is not initiated by a human. Simply warning that 'an error occured - please try again' would not make sense since the users are not trying to do anything.
Please feel free to ask more questions if you need more detail.
edit after some more thought on this
I think I may have misunderstood the CAS token. I think the token only changes upon update so the above is not a problem. still, I'll leave it just in case anyone else has some wisdom to add.