5

I have created simple CRUD api using Spring Data JPA in my Spring boot application.My Post method in the controller looks like below:-

@RequestMapping(value = "/article", method = RequestMethod.POST, produces = "application/json")
public Article createArticle(@RequestBody Article article) {
    return service.createArticle(article);
}

Service Method is as follows:-

@Override
public Article createArticle(Article articleModel) {
    return repository.save(articleModel);
}

My JsonPayload looks like below:

{
   "article_nm":"A1",
   "article_identifier":"unique identifier"
}

Now I want to make my POST request as Idempotent so that even if i got the json payload with the same article_identifier again It would not create a record in DB.

I can't do any scheme/constraint change in database and article_identifier field is also not primary key in table.

I understand that first I can check in database and return the saved record in response if it already exists but here if multiple request (original and duplicate request) comes at same time, both will check in database and would not find any record with that identifier and will create 2 record (one for each). Also as it's a distributed application how can i maintain the consistency across multiple database transactions.

How can I use some locking mechanism so that there would not be 2 records with same article_identifier ever. Can somebody please suggest some refers how to implement it in Spring boot ?

3
  • Is article_identifier the primary key in the database? Commented Jul 20, 2020 at 20:05
  • @kavithakaran No it's not.I have already mentioned the same in my post.
    – Manish
    Commented Jul 21, 2020 at 3:04
  • Not related to the problem, but please note that in REST architecture GET, PUT and DELETE are meant to be idempotent. Doing so with POST might confuse API consumer. Commented Dec 24, 2020 at 16:41

1 Answer 1

4

Idempotency in this case is needed to solve the post-back (or double post request). The simples way would be just to check at the service level whether a post with a given information exists (as you pointed out). You can use repository.exists() variations for that.

I understand that first I can check in database and return the saved record in response if it already exists

As for

if multiple request (original and duplicate request) comes at same time, both will check in database and would not find any record with that identifier and will create 2 record (one for each)

You need to isolate the transactions from each other if it is a single database (I know you said it is not, but I'm trying to explain my reasoning so bear with me). For that spring has the following anotation: @Transactional(isolation = Isolation.SERIALIZABLE). Although in this case @Transactional(isolation = Isolation.REPEATABLE_READ) would be enough.

Also as it's a distributed application how can i maintain the consistency across multiple database transactions.

How is it distributed? You first need to think about the database. Is it a master-slave mysql / postgress / mongodb ? Is it some weird globally distributed system? Assuming it is the traditional master-slave setup then the write transaction will be handled by the master (to my knowledge all the selects belonging to the transaction will also be there) so there should be no problem. However the answer can only really be given if more details are provided.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.