1

My question is that I am trying to develop a NodeJs REST service using which people can Register themselves on my site.My registration flow is something like this:

1.Check if any user exits with the same email

  1. If the user exists , send a response to tell that user already exists

  2. If user does not exists, create a user object with the entered details.

4.Now Insert this into DB.

  1. Send a response that the user is been registered.

Now let's say I have two users "A" and "B" , they entered same email ids , Now let's say User A and B both reaches a point where my code will check if the user exits or not, they both will get that user does not exists and their flow will move towards to create the object and create a object on DB. Now in this case if there is an synchronised block as we have in Java , we can prevent these two cases to create object at the same time, but in NodeJS how can I make this happen? and how to avoid this race round situation??

Does NodeJs being single threaded and having a common stack will prevent this from happening? or if there is any other way to do this in NodeJs? I am very new to NodeJs , I am sorry if I have mentioned something wrong.

bhalu007
  • 131
  • 1
  • 10
  • 1
    The easiest way around this is not by abandoning async model, but by properly designing the database. If `email` is declared as a unique index, then B will get an error when it tries to create a record. Handle this error and everything is fine. (This way you don't even need to check whether the user exists - just try to make it and refuse if the database throws an integrity error.) – Amadan Nov 06 '17 at 06:29
  • I wanted to handle it on the application level – bhalu007 Nov 06 '17 at 06:47
  • You can write your own semaphore in JS: it's just a simple boolean variable that both asynchronous processes can access. – Bergi Nov 06 '17 at 07:25

1 Answers1

2

So strictly speaking, node.js runs on one thread, but your program workflow, wich include I/O (database, filesystem), client and everything, runs on many thread.

Source: Can node.js code result in race conditions?

What can I do to prevent?

You can prevent this situation in database level using transactions. Or you can prevent in application layer too.

Database Layer

You can use (and should use) transactions (assume SQL) to ensure data consistency and integrity.

Application Layer

Additionally, track the register status in memory using hashmap for entered emails:

var PENDING_EMAILS = {}

app.post("/register", function(req, res) {

    var email = req.body.email

    if(PENDING_EMAILS[email]) {
        return res.send("Email is busy")
    }

    PENDING_EMAILS[email] = true // check this email as busy
    // register operation
    // check in DB etc...

    delete PENDING_EMAILS[email] // also, release hashmap key when register finishes or when there is an error

})

This approach prevents your problem.

Ozgur
  • 3,738
  • 17
  • 34
  • Thanks Ozgur GUL , I was looking for an application layer solution only, Thanks for the solution, I will test it and will see if it works – bhalu007 Nov 06 '17 at 06:48