Christian Fazzini
Christian Fazzini

Reputation: 19713

Understanding atomic operations and race conditions

Lets say I have a collection with a views_count, males_views_count and females_views_count fields. I would like to be able to $inc (increment) the count fields respectively when a page is viewed.

The issue with this is I receive several concurrent connections, and a race condition may occur.

I've been reading about atomic operations in Mongodb. Where they typically have a succeed or fail approach. Either the record is written or it isn't. Does that mean I need to create the logic to determine whether the operation failed and if so, retry it?

Going back to my scenario. What if I wanted to make every view count (even when a race conditions occur). I know Mongodb locks are slightly different than traditional RDBMS'. Typically, I would implement an optimistic locking technique. Similar to:

begin
  # .. do work .. determine if user is a male or a female
  stat.save
rescue StaleDocumentError
  stat.reload
  retry
end

Or are atomic operations meant to prevent race conditions as it is the server who does the update and it is authoritative about what the truth is? If so, do we still need to implement optimistic/pessimistic locking techniques, or will Mongodb take care of that for us if we use atomic operations?

Upvotes: 1

Views: 2533

Answers (1)

Stennie
Stennie

Reputation: 65303

If you are using atomic operations such as $inc there is no race condition. If you have two increments from different threads they will be applied in the order received by the server and the end outcome on the document will be the same after both operations are applied.

If you are updating fields to specific values using $set, the "winning" value will be the last $set applied. If your application use case may lead to conflicting updates of the same field, then optimistic locking/versioning would be useful.

As far as exception handling goes, you should assume that any database operation could potentially result in a server exception (network error, duplicate key, ...) and retry as appropriate. There isn't any special logic required for atomic updates versus non-atomic updates, unless you choose to implement your own optimistic locking (in which case you would probably refetch the current version of the document and retry the operation).

The MongoDB manual covers a few different patterns in Isolate Sequence of Operations.

Upvotes: 3

Related Questions