1

I am writing a workflow Spring Boot Web Application where two people can read the same data and update it. I wand to handle write-write conflict using Spring JPA.

For an example, initial value of price=1000; User A and B read price from database. Now user B updates value of price to price=1500. After few second, User A updates price to price=2000 - This should throw an Exception because User A is trying to write(update) the already updated value by User B.

Currently I have marked column version with @Version annotation in Spring JPA. But I am not getting how to use it while updating.

Following is my code.

Entity Class

@Entity
class Product{
 @Version
 private int version;

 private String productName;

 private double price;

 /* Getters and Setters */
}

Spring JPA DAO

public interface ProductRepository extends JpaRepository<Product, Integer> {
}

Service Class

public class ProductService{

@Autowired 
ProductRepository productRepo;

@Transactional
public void updateProductPrice(int id,double price){

 Product p=productRepo.findOne(id);
 p.setPrice(price)
    // This is where price is being updated and write-write conflict needs to be handled.
    productRepo.save(p);
 }

}

Could anyone help me with any Spring API that can be used. Considering there is a @Version column. Any help would be appreciated. Thanks

Mansoor
  • 1,157
  • 10
  • 29
  • 3
    Possible duplicate of [Implementing Optimistic lock using Hibernate and Spring](http://stackoverflow.com/questions/19454003/implementing-optimistic-lock-using-hibernate-and-spring) – Alan Hay Sep 23 '16 at 21:44
  • http://stackoverflow.com/a/19456821/1356423 and http://stackoverflow.com/a/30101542/1356423 – Alan Hay Sep 23 '16 at 21:44
  • If I understand correctly, you are looking for a way to prevent a write if the value being overwritten (`price` in your case) does not have the same value as the one initially read. Plus, there could be a significant lag (seconds, minutes, etc.) between read and write and it is not necessary that multiple users perform a write at the same time. If this is correct, you are not looking at a concurrent write scenario and hence default JPA optimistic locking (provided by `@Version`) will not help you. You can try using the old price as the `@Version` column. – manish Sep 24 '16 at 04:43

1 Answers1

0

What you are trying to implement is called optimistic locking. There are two different ways how to ensure that the entity will be access or modified by only one resource at the time, optimistic and pessimistic locking.

These are bit more advanced topics so I would recommend you further reading before you make a decision which one is more suitable for your application (but rule of thumb is to use optimistic locking when you don't expect many collisions). See this tutorial or Spring Data excellent documentation.

Petr Mensik
  • 26,874
  • 17
  • 90
  • 115
  • Thanks. But this approach would be for concurrent writes. I have implemented Optimistic Lock for concurrent writes. Please consider the case where 2 writes have interval of seconds/minutes between them. – Mansoor Sep 23 '16 at 18:51
  • And what is the problem? The exception should occur when the seconds user transaction commits. – Petr Mensik Sep 23 '16 at 18:56
  • Correct, the exception should occur when the second user transaction commits. Consider this, reads will happen in a separate user GET request, and when user updates, a new POST request is made. – Mansoor Sep 23 '16 at 19:06
  • I am not sure what do you mean here? Doesn't really matter how and when the request is made, locking is always done by JPA and it comes to play only when two request are in conflict at the same time. – Petr Mensik Sep 30 '16 at 10:05
  • downvote was by mistake I am unable to upvote back again mistake. Sorry :( And thanks for your response :) – Mansoor Oct 01 '16 at 08:54