Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 混合优化/悲观锁 应用程序_Java_Jpa_Concurrency_Optimistic Locking_Pessimistic Locking - Fatal编程技术网

Java 混合优化/悲观锁 应用程序

Java 混合优化/悲观锁 应用程序,java,jpa,concurrency,optimistic-locking,pessimistic-locking,Java,Jpa,Concurrency,Optimistic Locking,Pessimistic Locking,嗨 我们有一个应用程序(J2EE/Hibernate/JPA),几个用户在一个公共实体上执行操作 为了简化,假设此应用程序类似于谷歌文档: 一个共享文档,其中多个用户可以同时更新 我们选择了optmistic锁来处理并发: 句子是独立的实体 很少有机会几个用户同时更新同一句话 在这种情况下,其中一个用户可以收到消息“对不起,另一个用户试图编辑相同的句子” 后台进程 到目前为止,一切顺利 但是现在,我们在这个应用程序中添加了后台进程(相当快的进程)。 他们定期做出改变(比如用一个词替换另一个词

我们有一个应用程序(J2EE/Hibernate/JPA),几个用户在一个公共实体上执行操作

为了简化,假设此应用程序类似于谷歌文档: 一个共享文档,其中多个用户可以同时更新

我们选择了optmistic锁来处理并发:

  • 句子是独立的实体
  • 很少有机会几个用户同时更新同一句话
  • 在这种情况下,其中一个用户可以收到消息“对不起,另一个用户试图编辑相同的句子”
后台进程 到目前为止,一切顺利

但是现在,我们在这个应用程序中添加了后台进程(相当快的进程)。 他们定期做出改变(比如用一个词替换另一个词)

那些工作失败是可以的。他们的任务并不紧急,他们可以在下一次(10秒后)尝试相同的任务

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

实际上,如果用户更改整个文档的字体(在所有句子上),并且此操作需要一段时间(>10秒),那么在此期间,后台进程将更改一些单词,较长的操作(=用户操作:更改字体)将在并发访问时失败

这是不可接受的向用户显示此消息:“您的操作失败,因为某些技术过程正在同时运行”

由于后台进程可以在以后重试,我们宁愿让它失败

问题 我们如何在乐观锁方法中为某些操作设置悲观锁

潜在解决方案 为了让用户保持乐观的态度,我们考虑了以下解决方案:

  • 创建一个“用户操作”标志,该标志将在任何用户的任何操作期间设置
  • 只有当此标志处于“关闭”状态时,作业才会启动
  • 在任何运行的进程结束时,检查标志是否打开:如果是,取消此操作/回滚
这样,进程将只能在空闲时间运行,而用户不做任何事情

帮助 这是一个好方法吗? 我们找不到任何关于混合类型锁的良好实践的文章/讨论。

对于“文档”,这是典型的读写锁案例

读写锁的工作原理是,多个读卡器可以并行地锁定资源,但只能锁定一个写卡器。因此,读者和作者是相互排斥的

真正的用户在开始编辑时会对文档设置“读取”锁定。他们中的多人可以同时输入,每个人将编辑不同的句子

您的后台进程是编写者在这种情况下,如果没有读者(和其他编写者)锁定此文档,它可以进入(通过放置“写”锁)。然后后台进程可以进行更改

此外,用户可能无法打开文档,但由于后台进程很快,因此不太可能(而且这是暂时的,您可以在1秒后重试,即使不通知用户)

为了给您提供一些参考,以下是如何使用JPA中的
LockModeType.READ
LockModeType.WRITE