Chor Wai Chun
Chor Wai Chun

Reputation: 3236

Spring Boot race condition on updating same entity

For spring boot, i understand that if I have a function that say, to reduce balance of user, we can use @Transactional annotation like below in a service method:

@Transactional
public void reduceBalance(long userId, BigDecimal usage) {
    ...
}

But my question isn't referring at placing control at specific function, I'm wondering below:

public void updateAge(long userId, int newAge) {
    User theUser = userRepository.findById(userId).orElse(null); // Line A-1
    theUser.setAge(newAge); // Line A-2
    userRepository.save(theUser); // Line A-3
}

public void updateName(long userId, String newName) {
    User theUser = userRepository.findById(userId).orElse(null); // Line B-1
    theUser.setName(newName); // Line B-2
    userRepository.save(theUser); // Line B-3
}

Let say if 2 requests comes in at exactly same time, Line A-1 and B-1 is executed at same time, follow by A-2 and B-2, then A-3 and B-3.

Will B-3 overwrite A-2 changes? If yes, does it means we should be putting @Transactional annotation almost in every services, or is there actually a better design?

Upvotes: 1

Views: 1357

Answers (1)

Jonathan JOhx
Jonathan JOhx

Reputation: 5978

It is highly recommendable use @Transaction in each service but if you want to manage by different ways to do it, Other way is using @Version annotation

 Specifies the version field or property of an entity class that
 serves as its optimistic lock value.  The version is used to ensure
 integrity when performing the merge operation and for optimistic
 concurrency control.

Upvotes: 1

Related Questions