Я реализует некоторые бизнес-логики/проверки с хранилищами Rest и JPA Spring Data с помощью валидаторов хранилища, как описано в:Spring Data Rest границы транзакции
http://docs.spring.io/spring-data/rest/docs/current/reference/html/#events.
После углубления в код SDR я заметил, что валидаторы (или, в более общем смысле, репозитарии) не вызывают транзакции.
Из исходного кода org.springframework.data.rest.webmvc.RepositoryEntityController
:
private ResponseEntity<ResourceSupport> createAndReturn(Object domainObject, RepositoryInvoker invoker,
PersistentEntityResourceAssembler assembler, boolean returnBody) {
// validation logic is implemented in the listener, no transaction yet
publisher.publishEvent(new BeforeCreateEvent(domainObject));
// invoker calls repository, which is wrapped in the transactional proxy,
// only then transaction begins
Object savedObject = invoker.invokeSave(domainObject);
publisher.publishEvent(new AfterCreateEvent(savedObject));
PersistentEntityResource resource = returnBody ? assembler.toFullResource(savedObject) : null;
HttpHeaders headers = prepareHeaders(resource);
addLocationHeader(headers, assembler, savedObject);
return ControllerUtils.toResponseEntity(HttpStatus.CREATED, headers, resource);
}
Как видно в коде, слушатели не называется в рамках транзакции, что может привести к возможным проблемам непротиворечивости данных.
Я что-то упустил? Или структура просто неправильно устанавливает транзакционную границу?
Я думаю, что он спроектирован таким образом. Событие «До» должно быть отправлено до сохранения и должно быть успешным независимо от успеха сохранения. Это общий подход весны, SDR только следует за ним. По моему мнению, невозможность приложить дополнительную логику к операциям репозитория делает всю концепцию едва пригодной. Поэтому мы должны использовать пользовательские контроллеры в 80% случаев. –
Ну, я не совсем уверен, что события «до» не зависят от фактического вызова. В SDR [documentation] (http://docs.spring.io/spring-data/rest/docs/2.4.4.RELEASE/reference/html/#validation) предлагается использовать валидаторы как прослушиватели событий, таким образом фактический вызов репозитория зависит от успеха проверки. Во всяком случае, я понимаю, что базовая реализация Spring Data может не обязательно быть JPA, но заявить простую заметку о транзакциях в документах было бы действительно приятно :) –
Если ваши слушатели событий должны принять участие в более крупной транзакции, то вы, скорее всего, не нужны прослушиватели событий, а полноценный сервис. В документации четко указано, что Spring Data REST просто предоставляет хранилища. – zeroflagL