【问题标题】:Multiple PATCH requests REST End Point多个 PATCH 请求 REST 端点
【发布时间】:2016-04-26 11:24:41
【问题描述】:

我有一个 Spring Data Rest 项目,它公开了一个由 JPA 和休眠管理的实体。 我使用多个 PATCH 请求更新了实体中的多个多对多关系。

所以我将 PATCH 请求发送到端点,实体 url 列表作为每个多对多关系的主体。

补丁请求同时发生,所以一个请求被处理,第二个并发请求给出

行被另一个事务更新或删除(或未保存值映射不正确)

有没有办法同时修补实体? 示例实体就像,

User {

List<Role> roles;  

List<Module> modules;

}

Role 和 Module 都发生并发修补请求。
编辑:这是我用来修补的 Angular 代码。

   var patchRequests = [];
   angular.forEach(copy, function (value, property) {
                    if (angular.isArray(copy[property])) {
                        // If array contains more than zero elements
                        if (copy[property].length > 0) {
                            patchRequests.push(
                                $http.patch(url,copy[property].join('\n'), {
                                    headers: {
                                        'Content-type': 'text/uri-list'
                                    }
                                }));
                        }
                    }
                });
    $q.all(patchRequests);

“复制”对象如下所示

{"roles":["http://localhost:9002/api/roles/1","http://localhost:9002/api/roles/3"],"modules":["http://localhost:9002/api/modules/1"],"subModules":[],"userName":"hrandika","password":"password","email":"h@local","activated":true}

编辑 2: Spring Data rest 只是一个接口

@Repository
public interface UserRepository extends PagingAndSortingRepository<User, Long>{

}

【问题讨论】:

  • 向我们展示您进行修补的代码。
  • @RobertMoskal 我已经添加了 AngularJS 代码和我用来修补的对象。只需遍历对象属性,选择数组,如果数组长度> 0,则发送一个 PATCH。
  • 这是我认为我们需要查看的服务器端端点。
  • @RobertMoskal 我已经添加了 Edit 2。它是一个用 '@Repository' 注释的界面

标签: angularjs spring-data-rest


【解决方案1】:

根据HTTP Patch 规范:

服务器必须以原子方式应用整个更改集,并且永远不会 提供(例如,在此操作期间响应 GET)a 部分修改的表示。如果整个补丁文件 无法成功应用,则服务器不得应用任何 变化。

单个补丁请求完成的所有更改都必须是原子的。这是在 Java 中通过使用容器或数据库管理的事务来实现的。

因此,如果两个客户端向服务器发送补丁,则其中一个客户端必须等到第一个客户端完成他的工作或应该失败。

由于补丁可以更新任何字段(甚至是其他资源),因此两个单独的补丁请求可能会以不同的方式更新同一字段(类似于 DB 竞争场景中使用的乐观锁示例)。除此之外,补丁指令通常应包含将状态 1 转换为状态 2 所需的步骤。JSONPatch f.e.一个请求可以从集合中删除一个字段,而另一个请求会尝试将项目移动到另一个位置。由于这两个请求都依赖于它们当前知道的状态,因此盲目地应用这些值可能很危险。

不过,HTTP 补丁规范也提供了有关如何处理多个补丁请求的冲突场景的提示:

可以以幂等的方式发出 PATCH 请求, 这也有助于防止两者之间的碰撞产生不良后果 在相似的时间范围内对同一资源的 PATCH 请求。 来自多个 PATCH 请求的冲突可能比 PUT 冲突,因为某些补丁格式需要从 已知基点,否则它们将破坏资源。客户 使用这种补丁应用程序应该使用条件请求 这样如果资源已更新,请求将失败 自客户端上次访问资源以来。例如,客户端 可以在 PATCH 的 If-Match 标头中使用强 ETag [RFC2616] 请求。

因此,我建议遵循规范并使用 ETag 和 If-Match HTTP 标头来防止多个补丁请求发生冲突。

【讨论】:

  • 感谢您的信息。我将在 Spring 数据休息上下文和 AngularJS 中对其进行研究,
猜你喜欢
  • 2015-09-11
  • 2021-04-11
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
  • 1970-01-01
  • 2021-06-03
  • 2021-09-02
  • 1970-01-01
相关资源
最近更新 更多