NoSQL Zone is brought to you in partnership with:

I am a software architect passionate about software integration, high scalability and concurrency challenges. Vlad is a DZone MVB and is not an employee of DZone and has posted 70 posts at DZone. You can read more from them at their website. View Full User Profile

MongoDB and Optimistic Locking

11.12.2013
| 8689 views |
  • submit to reddit

When moving from JPA to MongoDB, you start to realize how many JPA features you've previously taken for granted. JPA prevents "lost updates" through both pessimistic and optimistic locking. Optimistic locking doesn't end up locking anything, and it would have been better named optimistic locking-free or optimistic concurrency control, because that's what it does anyway.

So, what does it mean to "lose updates"?

A real-life example would be when multiple background tasks update different attributes of some common Entity.

optimisticlocking

In our example we have a Product Entity with a quantity and a discount which are resolved by two separate batch processors.

  1. the Stock batch loads the Product with {quantity:1, discount: 0}
  2. the Stock changes the quantity, so we have {quantity:5, discount: 0}
  3. the Discount batch loads the Product with {quantity:1, discount: 0}
  4. the Discount changes the discount, so we have {quantity:1, discount: 15}
  5. Stock saves the Product {quantity:5, discount: 0}
  6. Discount saves the Product {quantity:1, discount: 15}
  7. the saved quantity is 1, and the Stock update is lost

In JPA you may provide the @Version field (usually an auto-incremented number) and Hibernate takes care of the rest. Behind the scenes there is a safety mechanism that checks the updated rows number given a specific version. If no row was updated, then the version has changed and an optimistic locking exception is thrown.

UPDATE Product
SET quantity=1, discount=15
WHERE version=1; 

But if your storage is not a RDBMS system, but a Mongo database instead, you still want to prevent lost updates. Luckily Spring Data comes to the rescue, as it provides a set of Document oriented annotations, among which you can find a @Version annotation with the same semantic as its JPA counterpart.

An automatic retry mechanism should also be employed, as an optimistic locking exception is a recoverable one. It only needs to reload the latest Entity snapshot, merge the specific attributes and update.

So, Spring Data offers more than base repository support and simple query automation. The optimistic locking add-on provides the proper level of write consistency required by your application QoS.

Code available on GitHub

Published at DZone with permission of Vlad Mihalcea, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Nicolas Bélisle replied on Tue, 2013/11/12 - 10:06am

I'm not very familiar with MongoDB, so please correct me. The default mechanism that can be used for optimistic locking is : http://docs.mongodb.org/manual/reference/command/findAndModify/

Is that what Spring Data uses ?

Vlad Mihalcea replied on Tue, 2013/11/12 - 4:55pm

Hi Nicolas,

The spring-data-mongodb 1.2.0 I'm currently using employs a simple update operation to achieve this behavior. The update may take a query parameter, thus restricting what we expect to update, similar to the Hibernate inner mechanism. Actually you can also use findAndModify for optimistic locking, but if you are not really interested in retuning the old object data (the default behavior) or the new one (using the 'new' parameter), then an update operation would be sufficient.

If you're only interested in optimistic locking, then you can manually add this behavior without to much effort, on top of your MongoDB driver. 

There is more to Spring Data than optimistic locking. We chose Spring Data because we didn't want to write generic DAO classes, and most of our simple queries can be automatically generated without needing anything else but a proper method naming.

We have first used it for JPA and when we decided we also need MongoDB in our project, it felt natural to check the Spring Data MongoDB support. In the beginning we used the Repositories, Converters, and the base annotations support. But then we also discovered the benefit of the @Version annotation, which was not advertised as I think it should.

Vlad

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.