Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use optimistic locking with Spring Data MongoDB?

I'm going through Spring Data MongoDB - Reference Documentation and I'm finding the examples to be a bit too simplistic.

In particular I'm trying to understand how to handle stale data in concurrent environments. For instance, imagine I have the following entity:

public class Person {

    private final String username;
    private final String firstname;
    private final String lastname;

    [...]

}

Now if I use CrudRepository to save/update/remove my entities, then imagine a scenario in which two threads retrieve the same entity, one of them removes it, and the other one updates its lastname field. If the delete call completes before the save call then my entity will be removed and then re-created, when the expected behaviour would be for the save operation to fail.

So far I've seen two options for getting around this issue:

  1. Use @Version annotation. Could not find any documentation saying Spring Data supports optimistic locking in MongoDB using versioned documents. If anyone can point me to a link it'd be appreciated.
  2. Use MongoOperations.findAndModify and fail if it returns null. The downside to this approach is that I can no longer implement my repository API to have "get entity" and "save updated entity" kind of semantics. e.g.:

    User user = userRepository.findByUsername("uniqueUsername");
    user.setLastName("Archer");
    userRepository.update(user);
    

I would have to push some of this to the repository I guess:

userRepository.updateLastname("uniqueUsername", "Archer");

But I'm a little bit worried my repository interfaces will grow uncontrollably if every type of update I want to do requires a new method.

I realise I haven't actually stated a question yet, so here it goes: what's the best-practice for designing an application using Spring Data for MongoDB?

like image 244
user2722238 Avatar asked Aug 19 '15 01:08

user2722238


People also ask

Does MongoDB support optimistic locking?

Mongo has had a lot of work done to strengthen its distributed story (see the Jepsen analysis), it has no built-in support for optimistic concurrency control at a document level.

How do you implement optimistic locking?

In order to use optimistic locking, we need to have an entity including a property with @Version annotation. While using it, each transaction that reads data holds the value of the version property. Before the transaction wants to make an update, it checks the version property again.

Can we use Spring data JPA with MongoDB?

Yes, DataNucleus JPA allows it, as well as to many other databases.

What is optimistic locking MongoDB?

Optimistic locking is a bit different. Instead of denying something to others, we make sure we are not the ones breaking the data. This is ensured by keeping track of the object's version we are working with and checking, that we only update the DB record if it's version hasn't changed.


1 Answers

Using @org.springframework.data.annotation.Version on a property should do the trick. I've created DATAMONGO-1275 to improve the documentation on that.

like image 177
Oliver Drotbohm Avatar answered Sep 30 '22 13:09

Oliver Drotbohm