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

时间:2017-10-18 15:40:29

标签: jpa concurrency etag

我刚刚发现Etags可以帮助我处理一个资源上的并发更新。 但在我看来,Etags仅仅不足以处理并发性。 也许我错了,所以我想征求你的意见。

以下是一个用例:

  • 设O为O.text =«Hello»
  • 之类的对象
  • 让A和B成为两个用户
  • A想要修改O,例如O.text =«Hello A»
  • B想要修改O,例如O.text =«Hello B»

应该允许用户持久保留对象修改 如果对象的状态未被另一个修改过 自从读取对象状态

以下是仅通过Etags处理并发的方案:

  1. 使用Etag = [hash_O]
  2. 的用户更新请求
  3. 从数据库中读取对象
  4. 为对象O创建Etag。结果是[hash_O]
  5. 比较Etags(用户请求中的那个和创建的请求) 数据库读后)
  6. Etags相等
  7. 在数据库中更新O
  8. 在我看来,用户 A和B可以在步骤5中同时到达。 所以有可能A使用“Hello A”更新O.name并且在B更新O.name之后使用“Hello B”,尽管O的状态刚刚更改。

    您是否同意这种情况?

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

    • 应该是2)到5)+数据库中的更新
    • 的所有步骤的副本
    • 但这一次,所有动作都应该在原子指令中执行
      • 即:使用JAVA中的同步方法

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

    • 您同意我的分析吗?
    • 或者我有任何误解吗?

    因此,除了ETag之外,也可以使用JPA中的注释@version。

    提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

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

要在更新时满足If-Match ETag语义,您必须避免您描述的竞争条件。现在,是否存在竞争条件以及如何避免它将取决于实施。 ETags的定义没有任何内容要求资源是对象,它们在数据库中持久存在,ETag是哈希等等。

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

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