简体   繁体   中英

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?

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.

// 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.

Here if you use system calls method in frontend then you should fire one request to frontend from Database when some user like, I send you request then within a sec database send you one system call and your frontend code immediate correct the button text like

"Add a friend" to "incoming request"

or else.

if you are only setting up database then just make a system call which send it to UI when friend request arrives or as you say Document created, the further process will be handled by UI Developer. Thank you. if you don't like the answer then I m apologize for that but don't downvote me because IM new in Stack Overflow Community.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM