使用hibernate的乐观/悲观锁定实现并发的良好策略/解决方案

时间:2017-02-16 17:29:33

标签: java hibernate rest concurrency locking

我们假设我们有一个应用程序"邮件客户端"和它的前端。

如果用户正在键入消息或编辑主题或其他内容,则进行休息调用以更新用户正在更改的内容(例如接收者)以将消息保留在DRAFT中。所以很多PUT正在发生以保存消息。关闭窗口时,每个可编辑字段的更新同时发生。 Hibernate无法处理这种并发:每个调用都会检索消息,编辑自己的字段并尝试再次保存消息,而另一个调用已经改变了它。

我知道我可以添加一个休息调用来同时保存所有字段,但我想知道是否有更清晰的解决方案,或者处理此类情况的合适策略(例如仅更新一个字段或某些合并策略,如果对象已经更改)

提前致谢!

1 个答案:

答案 0 :(得分:0)

这里最简单的解决方案是将UI调整为

  • 在电子邮件提交期间提交一个休息电话,完成所有必要的任务。
  • 序列化其余的调用,以便它们被链接而不是同时触发。

我在这里担心的是,随着越来越多的用户与应用程序交互,这会在某些时候滚雪球并成为更大的并发问题。暂时考虑当您面对100,500,1000甚至10000或更多并发用户时,您的Web基础架构必须单独支持的并发休息呼叫的潜在数量。

当负载本身是设计缺陷的产物时,加强服务器来处理负载是否真的有意义?

Hibernate旨在通过两种机制来处理锁定,乐观和悲观。

乐观的方式

  1. 从数据存储中读取实体。
  2. 在临时变量中缓存您要修改的字段的副本。
  3. 根据您的PUT操作修改字段。
  4. 尝试合并更改。
  5. 如果保存成功,您就完成了。
  6. 如果发生OptimisticLockException,请从数据存储中刷新实体状态。
  7. 将缓存的值与您必须更改的字段进行比较。
  8. 如果值不同,您可以断言或抛出异常
  9. 如果他们没有区别,请回到4。
  10. 乐观方法的优点在于避免发生任何形式的死锁,特别是如果您允许分别读取和锁定多个表。

    虽然您可以使用悲观锁定选项,但乐观锁定通常是处理并发操作的最佳方式,因为它具有最少的并发争用和性能影响。