The node cache does not know the purpose of any fields nor anything about "users" and so has no way of knowing that "reputation" of "my" nodes nor "experience" of "me" are things that "I" should never need to update. Plus, I do update my own experience because I can get experience points when I vote for other people's nodes.
Locking a record doesn't do any good unless you read the record when you obtain the lock. This requires that either the record remain locked while it is being viewed ("pessimistic locking", certainly unacceptable in our environment) or that the locked record be compared against the record originally viewed and have the update fail (not be performed) if the comparison fails ("optimistic locking").
So we'd have to provide an interface for notifying a user that whatever they last attempted has failed (you probably think this would be trivial). Since what the user attempted might apply to more than one node (up voting should increment the node's reputation, decrement the voter's number of votes, and might increment the author's experience), we'd have to have "transactions" so that a failure would attempt to undo the previously successful updates. MySQL doesn't support transactions nor client control over locking. So this would be a huge amount of work for little gain.
It is easy to say "oh, just lock it" and not really think about the details of the problem, eh?
We actually have locking for wiki nodes and updates made by editors, but neither of those designs would apply well to these types of situations.
A much better solution is to not do increment and decrement updates via the normal means of:
my $NODE= getNode( ... );
$NODE->{reputation}++;
updateNode( $NODE );
but instead provide a function just for these types of updates so that they can be done atomically so that no locking is required:
my $NODE= getNode( ... );
addToField( $NODE, reputation=>1 );
my $USER= getNode( ... );
addToField( $USER, votesleft=>-1, experience=>1 );
This will probably cover the vast majority of cases of simultaneously updates to the same field.
But the original scheme I described is still needed so that the node cache knows which fields are being updated so that it can deal with the race conditions intelligently (as well as making many operations faster).
- tye (but my friends call me "Tye") |