2

Imagine there are two entities Children and Gifts. Let's say there are 1000 children and 10 gifts. Children will always try to grab available gifts, and gifts will be tagged to children on a "first come, first serve" basis.

Table structure

children table

+----+------+
| id | name |
+----+------+
|  1 | Sam  |
|  2 | John |
|  3 | Sara |
+----+------+

gift table

+----+---------+-------------+
| id |  gift   | children_id |
+----+---------+-------------+
|  1 | Toy Car |           2 |
|  2 | Doll    |           3 |
+----+---------+-------------+

Here the children_id is the child who grabbed the gift first.

In my application, I want to update the children_id in such a way that only the first child who initiated the request will get it and rest get a GiftUnavailableException.

How will I ensure that, even if a 1000 requests come at a time to grab a specific gift, only the first one will get it. Or how will I ensure that there are no race conditions for this update.

Are there any spring specific feature that I can make use of or are there any other ways.

I'm using spring-boot as my backend.

Athul Kc
  • 61
  • 4
  • Use `synchronized` if you have multiple threads on a single machine – Lino Apr 17 '19 at 12:14
  • 1
    1. Make sure to execute within a transaction. 2. Start by taking an exclusive lock on a `Gift` - say, `@Lock(LockModeType.PESSIMISTIC_READ) Gift findOne(Long id)`. 3. Once a `Gift` has been retrieved, immediately check that it has not been claimed. If yes, bail out (throw an exception, return an error, etc.). 4. If the gift has not been claimed, assign the claimant to it, and save. This way, many claims can be processed in parallel, as long as they are for different gifts, and at the same time, concurrent claims for the same gifts will be refused, even if they run on different machines. – manish Apr 18 '19 at 06:47

1 Answers1

0

I can't post a comment so here I go !

I assume you are using Spring Data JPA.

Then you should use @Transactional annotation : This mean that everytime you are requesting your database, you do a transaction :

  1. Begin Transaction
  2. Execute Transaction
  3. Commit Transaction

Lot of usefull informations about this (Read it !!): Spring @Transactional - isolation, propagation

You will need to seed your Transactional Isolation to Serializable and maybe change the propagation method.

And if you are not using Spring data JPA.. Well There is a synchronized keywords but I think it's a bit awful to use it here.

JuNi
  • 24
  • 3