混合乐观/悲观锁

3

应用程序

您好,

我们有一个使用J2EE/Hibernate/JPA技术开发的应用程序,多个用户可以对一个公共实体进行操作。

为了简化问题,可以将该应用程序视为类似于Google文档:

共享文档许多用户可以同时更新。

我们选择使用乐观锁来处理并发:

  • 句子是独立的实体
  • 很小的几率出现多个用户同时更新同一句子
  • 在这种情况下,可以给其中一个用户发送消息“对不起,另一个用户试图编辑相同的句子”

后台处理

到目前为止还好。

但现在,我们已经向该应用程序添加了后台处理(非常快),它们定期进行更改(例如替换单词中的任何出现次数)。

这些作业失败是可以接受的。它们的任务不紧急,可以在下一次尝试任务(10秒后)时再尝试。

在这种情况下,乐观锁存在的问题在于,现在单个用户无法对整个文档执行长时间操作

事实上,如果用户更改整个文档(所有句子的字体),并且此操作需要一段时间(>10秒),则同时后台处理将更改一些单词,并且较长的操作(即用户操作:更改字体)将在并发访问时失败。

向用户显示这条消息“由于某些技术进程正在运行,您的操作失败”是不可接受的

由于后台处理可以稍后重试,我们宁愿使其失败。

问题

如何在乐观锁的情况下为某些操作/参与者设置悲观锁

可能的解决方案

为了保持用户的乐观态度,我们想到了以下解决方案:

  • 创建一个"用户操作"标志,在任何用户的任何操作期间都将被设置
  • 作业在此标志为“关闭”时才开始
  • 在任何运行的流程结束时,检查标志是否打开:如果打开,则取消此操作/回滚

这样,只有在用户不做任何事情的空闲时间才能运行流程

帮助

这是一种好的方式吗? 我们无法找到有关混合类型锁的最佳实践的任何文章/讨论。

1个回答

1
对于“文档”,这是一个典型的读写锁案例。
读写锁的工作方式是,多个读者可以并行锁定资源,但只有一个写者。因此,读者和写者是互斥的。
当真实用户开始编辑时,他们会对文档进行“读取”锁定。其中的多个用户可以同时进入,每个用户将编辑不同的句子。
在这种情况下,您的后台进程是编写者,如果没有读者(和其他编写者)锁定此文档,则可以通过放置“写入”锁来进入。然后,后台进程可以进行更改。
此外,可能会发生用户无法打开文档的情况,但由于后台进程很快,这种情况非常不太可能发生(而且它是暂时的,您可以在1秒后重试,甚至无需通知用户)。
为了为您提供一些参考,以下是如何在JPA中使用LockModeType.READ和LockModeType.WRITE:JPA中的读写锁

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接