Cześć wszystkim,
Mam problem z testowaniem mechanizmu Optymistycznej Blokady w mojej aplikacji Spring Boot. W mojej abstrakcyjnej klasie encji mam pole @Version private Long id
. Metoda updatePerson
przyjmuje EditPersonCommand
, w którym znajduje się pole private Long version
.
Podczas testowania przez Postmana, podaję w commandzie wersję różną od tej w bazie, ale mimo to otrzymuję odpowiedź 200 OK, a encja jest aktualizowana, przy czym wersja w bazie rośnie o 1. Wygląda na to, że mechanizm działa, ale nie weryfikuje, czy wersja w command jest zgodna z wersją w bazie.
Pytanie się nasuwa takie, że skoro podnosi wersję o 1, to mechanizm działa. Jednak nie weryfikuje tego, czy wersja jest zgodna z tym, co jest w bazie, a tym, co przekazuję w commandzie.
Czy źle rozumiem działanie Optymistycznego Locka? Czy może on najpierw pobiera wersję z bazy przez findById
, a potem, jeśli wersja się nie zmieniła do końca transakcji, nie wyrzuca wyjątku?
I w takim razie, czy nie potrzebuję przekazywać wersji w commandzie, bo on pilnuje tego na poziomie transakcji findById
(version: 0) -> update (version: 0)?
Metoda do podglądu:
@Transactional
public PersonDTO updatePerson(Long id, EditPersonCommand command) {
Person existingPerson = personRepository.findById(id)
.orElseThrow(() -> new PersonNotFoundException("Person with id " + id + " not found"));
log.info("Existing person: " + existingPerson.getVersion());
modelMapper.map(command, existingPerson);
log.info("Existing person after mapping: " + existingPerson.getVersion());
validatePerson(existingPerson);
Person savedPerson = personRepository.persistAndFlush(existingPerson);
log.info("Saved person to DB: " + savedPerson.getVersion());
return convertPersonToDTO(savedPerson);
}
Jak dodaje sobie takiego ifa, to oczywiście wyjątek wyrzuca, ale powinno działać i bez niego.
if (!existingPerson.getVersion().equals(command.getVersion())) {
throw new OptimisticLockingFailureException("Version mismatch for Person with id " + id);
}
Z góry dziękuję za pomoc.