Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB Concurrency Issue

I have a scenario for my app which is similar to sending friend request in Facebook.

When user A sends friend request to user B, internally a new friend request document is created. At a later time when user B also wants to send friend request to A, system would find out that a friend request document existed and so they should be friend of each other, no new friend request document would be created.

I'm trying to figure out the case when user A and user B both simultaneously sends friend request to each other which will then create 2 friend request documents and leading to undetermined behaviour...

Thanks for your suggestions.. Really appreciated!

Edit: A few had suggested to use a request queue to solve this; however, I'm confused about using queue because i thought it would make my rest api endpoint process requests sequentially. Wouldn't I lose all the benefit of multi-threading by using queue? I can't help but imagine how bad it would be if my service has millions of requests queued and waiting to be executed one by one just due to this issue. Has anyone seen something along similar problems seen in production?

like image 757
user1955934 Avatar asked Dec 18 '15 03:12

user1955934


People also ask

Does MongoDB support concurrency?

MongoDB allows multiple clients to read and write the same data. To ensure consistency, MongoDB uses locking and concurrency control to prevent clients from modifying the same data simultaneously.

How many transactions per second can MongoDB handle?

Performance Scale After evaluating multiple technology options, AHL used MongoDB to replace its relational and specialised 'tick' databases. MongoDB supports 250 million ticks per second, at 40x lower cost than the legacy technologies it replaced.

What are the limitations of MongoDB?

The maximum BSON document size is 16 megabytes. The maximum document size helps ensure that a single document cannot use excessive amount of RAM or, during transmission, excessive amount of bandwidth. To store documents larger than the maximum size, MongoDB provides the GridFS API.


2 Answers

I had similar situation with my client which has concurrent writes in the database, What I have implemented is a Queue service.

Create a request in the queue rather than writing in the database, a separate reader will 
read one message from the queue at a time and check if it is valid to write it to 
database, write only if there is no previous request.

You can implement your own queue or you can use service like AWS-SQS, rabbitmq, MSMQ etc.

like image 52
Harshal Bulsara Avatar answered Oct 13 '22 00:10

Harshal Bulsara


// Specific to your case

  1. In mongodb write operations on a single document are atomic.
  2. mongodb has a feature of unique index.

Hence if you insert the document with an _id(or any other unique index) with person names A and B by creating unique index for both (such as "A_B" by lexicographically sorting the names) before doing insertion. You will inherently be able to insert only one instance of that document.

// General

What essentially we would like to have are transactions but since mongodb doesn't support such, as of now. There are a few tricks to achieve this:

  1. 2 phase commits : https://docs.mongodb.org/v3.0/tutorial/perform-two-phase-commits/

  2. Using an external source to maintain a flag, for example using memcache which supports insertion in transactional manner/Compare and Swap.

like image 23
Manjinder Aulakh Avatar answered Oct 13 '22 00:10

Manjinder Aulakh