除了 Etag 之外,我还应该有另一个系统来处理并发吗?

Should I have another system in addition to Etag to handle Concurrency?

我刚刚发现 Etags 可以帮助我处理对一个资源的并发更新。 但在我看来,仅 Etags 不足以处理并发。 也许我错了,所以我想请教你。

下面是一个用例:

当且仅当,应允许用户保留对象修改 如果对象的状态没有被另一个改变的修改 自读取对象状态.

下面是仅通过 Etags 处理并发的场景:

  1. 来自 Etag = [hash_O] 的用户的更新请求
  2. 从数据库中读取对象 O
  3. 为对象 O 创建 Etag。结果是 [hash_O]
  4. 比较Etags(用户请求的和创建的 读取数据库后)
  5. Etags 相等
  6. 更新数据库中的 O

在我看来,用户 A 和 B 可以在步骤 5) 同时到达。 因此,尽管 O 的状态刚刚发生变化,但 A 可能会使用 "Hello A" 更新 O.name 并且在 B 更新 O.name 之后会使用 "Hello B"。

您是否同意这种情况可能发生?

如果是这样,在我看来步骤 6) :

总而言之,我应该首先检查 Etags,如果测试成功,然后检查 Etag 并以原子方式在数据库中执行更新。

所以除了 ETag 之外,也许还可以使用来自 JPA 的注释 @version。

在此先感谢您的帮助!

是的,你的分析基本上是正确的。

为了在更新时满足 If-Match ETag 语义,您必须避免您描述的那种竞争条件。现在,是否存在竞争条件以及如何避免竞争条件将取决于实现。 ETag 的定义并不要求资源是对象,它们持久存在数据库中,ETag 是散列等。

对于某些体系结构,您可以使用原子数据库命令进行更新。对于其他人,您可能需要某个隔离级别的数据库事务。对于其他人,您可能需要某种锁或代码级同步原语。

我对 JPA 或您的特定架构了解不多,无法提供具体建议,但是,您是对的,这是您必须考虑并采取措施避免的问题。