Spring 数据剩余事务边界
Spring Data Rest transaction boundaries
我一直在使用 Spring Data Rest 和 JPA 存储库实现一些业务 logic/validation,使用存储库验证器,如下所述:
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);
}
如代码所示,不会在事务中调用侦听器,这可能会导致最终的数据一致性问题。
我错过了什么吗?或者框架只是错误地设置了事务边界?
在 spring 数据中,存储库方法将 运行 它自己的事务。我也认为这在某些情况下是有问题的。至少事件处理程序应该 运行 在与存储库方法相同的事务中。
这里有一个类似的问题:
Handle spring-data-rest application events within the transaction
特别是这个答案提供了一个解决方法,允许您将整个 RepositoryEntityController
方法包装在一个事务中 - 我认为这是您大部分时间需要的:
我一直在使用 Spring Data Rest 和 JPA 存储库实现一些业务 logic/validation,使用存储库验证器,如下所述:
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);
}
如代码所示,不会在事务中调用侦听器,这可能会导致最终的数据一致性问题。
我错过了什么吗?或者框架只是错误地设置了事务边界?
在 spring 数据中,存储库方法将 运行 它自己的事务。我也认为这在某些情况下是有问题的。至少事件处理程序应该 运行 在与存储库方法相同的事务中。
这里有一个类似的问题: Handle spring-data-rest application events within the transaction
特别是这个答案提供了一个解决方法,允许您将整个 RepositoryEntityController
方法包装在一个事务中 - 我认为这是您大部分时间需要的: