应用程序
你好,
我们有一个应用程序(j2ee/hibernate/jpa),几个用户在一个公共实体上执行操作。
为了简化,假设这个应用程序类似于google docs:
许多用户可以同时更新的共享文档。
我们选择了optmistic锁来处理并发:
句子是独立的实体
多个用户同时更新同一句话的可能性很小
在这种情况下,其中一个用户可以收到一条消息“对不起,另一个用户试图编辑同一句话”
后台进程
到目前为止,还不错。
但是现在,我们已经在这个应用程序中添加了后台进程(相当快的进程)。
他们经常做一些改变(比如说用另一个词代替任何一个词)。
那些工作失败是可以的。他们的任务并不紧急,他们可以在下次(10秒后)尝试相同的任务。
这种情况下乐观锁的问题是,现在单个用户无法对整个文档执行更长的操作。
实际上,如果用户更改整个文档的字体(在所有句子中),并且此操作需要一段时间(>10秒),则同时后台进程将更改一些单词,较长的操作(=用户操作:更改字体)将在并发访问时失败。
向用户显示此消息是不可接受的:“您的操作失败,因为某些技术进程同时运行。”
由于后台进程可以稍后重试,我们宁愿让它失败。
问题
如何在乐观锁方法中为某些操作/参与者设置悲观锁?
潜在解决方案
为了让用户保持乐观的态度,我们考虑了以下解决方案:
创建“用户操作”标志,该标志将在任何用户的任何操作期间设置
只有当此标志为“关闭”时,作业才会启动
在任何正在运行的进程结束时,检查标志是否打开:如果是,请取消此操作/回滚。
这样,进程只能在空闲时运行,而用户什么也不做。
帮助
这是个好办法吗?
我们找不到任何关于混合类型锁的良好实践的文章/讨论。

最佳答案

对于“文档”,这是典型的读写锁定情况。
读写锁的工作原理是,多个读卡器可以并行锁定资源,但只能锁定一个写卡器。正因为如此,读者和作家是相互排斥的。
当真正的用户开始编辑时,他们会给文档加上一个“read”锁。他们中有多个可以同时输入,每个人都会编辑不同的句子。
您的后台进程是writer,在本例中,如果没有读卡器(也没有其他写卡器)锁定此文档,则可以输入(通过放置“write”锁)。然后后台进程可以进行更改。
此外,用户可能无法打开文档,但-由于后台进程很快-这是不太可能的(而且是暂时的,您可以在1秒后重试,即使不通知用户)。
为了给您提供一些参考,下面介绍如何在jpa中使用LockModeType.READLockModeType.WRITERead-Write lockings in JPA

09-27 08:19