Reid Morrison
unread,Jan 6, 2012, 11:09:11 AM1/6/12Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to mon...@googlegroups.com
We are re-writing existing code that calls MongoDB directly through the Ruby driver to use Mongoid instead. We have one race condition where several servers may be processing the same identity at the same time. Each server after loading the Identity document needs to add a new first_name and last_name to an embedded list if it is not already there, along with a counter.
The challenge is that if 2 servers load the same document, they both see that the name is not already in the list, they will both perform a $push to add the name atomically with a count of 1 to the same identity document in Mongo. This results in the name being added twice to the list. To prevent this condition we added the $not to the where clause to ensure that the name had not already been added in the milliseconds since the document was retrieved, as follows:
identities.update(
{'_id' => identity['_id'], 'names' => {'$not' => {'$elemMatch' => {'first_name'=>first_name, 'last_name' => last_name}}}},
{'$push' => {'names' => {'first_name'=>first_name, 'last_name' => last_name, 'count'=>1}}},
{:safe => true}
)}
If the update fails to update any documents, it then does a $inc on the document since the name is now there.
Any suggestions on how to make this work in Mongoid?
Thank you
Reid