Spring Data Rest事务边界

时间:2016-02-23 21:36:56

标签: java spring transactions spring-data-jpa spring-data-rest

我一直在使用存储库验证器与Spring Data Rest和JPA存储库实现一些业务逻辑/验证,如下所述:

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);
}

如代码所示,侦听器不会在事务中调用,这可能导致最终的数据一致性问题。

我错过了什么吗?或者框架只是错误地设置了事务边界?

1 个答案:

答案 0 :(得分:2)

在spring数据中,存储库方法将运行自己的事务。我也认为在某些情况下这是有问题的。至少事件处理程序应该在与存储库方法相同的事务中运行。

这里有一个类似的问题: Handle spring-data-rest application events within the transaction

特别是这个答案提供了一种解决方法,允许您将整个block_table[[compared_attribute]] = block_table[[compared_attribute]].astype(int) 方法包装在事务中 - 我认为这是您大多数时间所需要的:

https://stackoverflow.com/a/30713264/5371736