MongoDB data integrity on a create command with a preceeding validation command

306 views Asked by At

A website I'm creating lets users have a unique subdomain on the site eg; gaz123.mywebsite.com.

They enter their subdomain when they register on the site. In the code before I create the account record I check that the subdomain they've chosen doesn't already exist. This is just a simple query against accounts with the same subdomain. If this returns a zero count then I proceed and create the account with that subdomain.

I have placed a lock() command around the two MongoDB commands ie; check that the subdomain is available and then create the account. Then I release the lock.

lock( m_oLockMe)
{
    if( SubdomainIsFree( oRegisterModel.SubDomain))
    {
        CreateAccount( oRegisterModel);
    }
}

Is this how you would do it? Is there another way that is better? Why?

Thanks

1

There are 1 answers

0
pingw33n On BEST ANSWER

This is not a good way - you lose scalability here. I'd do this with atomic findAndModify. First you'll need to establish unique index on subdomain field:

db.subdomains.ensureIndex({subdomain: 1}, {unique: true})

This is needed for upsert to not generate duplicates. Then you'll do this:

r = db.subdomains.findAndModify({query: {used: false, subdomain: <subdomain>}, update: {$set: {used: true}}, new: true, upsert: true})

This will either return document which represents free subdomain or throw duplicate key error which means the subdomain is used. For free subdomain this will also atomically set used to true so it's guaranteed only a single findAndModify operation will get the same document.