Question

I'm totally new to MongoDB. I'm using Morphia to access it from Java. I need to do something along the lines of this:

public boolean isUnique(short s){
//OPERATION 1: Check in mongo if object with field "id" = s exists
//if so, return false
//else,
//OPERATION 2: create this object in the database
//and return true
}

The problem for me to grasp is not the actual syntax, but the problem with atomicity. How do I assure that only one thread/process can have access to the document so that OP1 and OP2 are atomic? I think this has to be managed on a database level since the Java server is in a clustered environment.

Regards, Anders

Was it helpful?

Solution

You could replace both operations with one upsert of the {id: s} document that becomes a no-op if the document already exists, but an insert if it doesn't. Calling the getLastError command (the driver can do this for you) will tell you whether a new document was created or not.

OTHER TIPS

I'm using Java and Morphia so here is what the actual code looks like, if anyone should be wanting to achieve the same thing in the future. It's the true in the call to updateFirst that tell Mongo that it's an upsert:

public boolean checkIfExistsAndInsertOtherwise(short id){
    Datastore datastore = getDatastore();
    Query<OrganizationId> updateQuery = datastore.createQuery(OrganizationId.class).field("identificationNumber").equal(id);

    //Bogus operation, just set id to itself
    UpdateOperations<OrganizationId> ops = datastore.createUpdateOperations(OrganizationId.class).set("identificationNumber", id);

    UpdateResults<OrganizationId> result = datastore.updateFirst(updateQuery, ops, true,WriteConcern.SAFE);

    return result.getInsertedCount() == 0;
  }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top