Состояние гонки Spring Boot при обновлении того же объекта - PullRequest
1 голос
/ 19 апреля 2020

Для весенней загрузки, я понимаю, что если у меня есть функция, которая говорит, чтобы уменьшить баланс пользователя, мы можем использовать аннотацию @Transactional, как показано ниже в методе сервиса:

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

Но мой вопрос не Я имею в виду следующее:

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
}

Допустим, если 2 запроса поступают в одно и то же время, выполняется строка A-1 и B-1 Одновременно следуют A-2 и B-2, затем A-3 и B-3.

Перезапишет ли B-3 изменения A-2? Если да, значит ли это, что мы должны помещать аннотацию @Transactional почти во все сервисы, или на самом деле есть лучший дизайн?

1 Ответ

1 голос
/ 19 апреля 2020

Настоятельно рекомендуется использовать @Transaction в каждом сервисе, но если вы хотите управлять разными способами, другим способом является аннотация @Version

 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.
...