【问题标题】:How do you implement a coarse-grained optimistic lock in REST?如何在 REST 中实现粗粒度乐观锁?
【发布时间】:2013-01-18 14:50:57
【问题描述】:

我通过将 GET 中的版本号传递回 PUT 调用,为我的 REST 资源实现了乐观锁定,这些资源具有与数据库表的一对一映射。如果在我执行 GET 和 PUT 之间数据库中的版本号发生了变化,那么就发生了乐观锁异常。很简单的设计。

现在,我如何对映射到多个数据库表的复合 REST 资源执行相同的操作?我不想回传多个版本字段(一个用于与复合资源相关的每个数据表)。复合资源的一个简单示例是 /FooBar,其中 /Foo 和 /Bar 是非复合资源。

我基本上是在寻找 Fowler 粗粒度锁定模式的 REST 实现示例:http://martinfowler.com/eaaCatalog/coarseGrainedLock.html

【问题讨论】:

  • 在您的 REST 服务中,您是否可以只收集版本并将它们放入一个 Map 中,该 Map 由唯一生成的表示版本的 id 键入?然后将其发送给客户并让他们在编辑后将其发回给您?然后,您可以使用该 id 来获取实体图的版本。

标签: java rest optimistic-locking


【解决方案1】:

这就是ETag header 的设计目的。实现它的一种非常常见的方法是生成响应负载,对其进行哈希处理(它不必是安全的,只是低冲突),然后使用该哈希作为 ETag 的值。请注意,这种方法不知道产生响应涉及多少来源。

然后客户端将收到的ETag 发送回If-Match 标头中,服务器可以使用该标头检查请求的新鲜度。

【讨论】:

  • 如果不够“新鲜”,HTTP 服务器会发送一个409 (conflict) status code
  • 实际上是 412。见tools.ietf.org/html/…
  • 嗯,很有趣。规范是宽松的,因为 409 中的示例非常明确:“例如,如果正在使用版本控制并且被 PUT 的实体包括对资源的更改,这些更改与早期(第三方)请求所做的冲突,则服务器可能会使用 409 响应来指示它无法完成请求”。
  • 是的,但是您会注意到此处没有提到 ETag 和 If-Match。 409 用于未由 ETag 编码的任何冲突。请注意,该方法允许一个人对文档的一部分进行更改,如果它与先前请求更改的部分不同,则服务器可以继续合并它们而不会出错。 ETag/If-Match 无法做到这一点,它是一个“整个文档”的大锤。
猜你喜欢
  • 1970-01-01
  • 2016-05-23
  • 2013-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
相关资源
最近更新 更多