3

应用程序

你好,

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

为简化起见,假设此应用程序类似于Google 文档许多用户可以同时对其进行更新的共享文档。

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

  • 句子是独立的实体
  • 多个用户同时更新同一个句子可能性很小
  • 在这种情况下,一个用户可以收到一条消息“对不起,另一个用户试图编辑同一个句子”

后台进程

到目前为止,一切都很好。

但是现在,我们已经为这个应用程序添加了后台进程(相当快的)。他们定期进行更改(假设它用另一个单词替换任何出现的单词)。

那些工作失败也没关系。他们的任务不紧急,下次(10 秒后)可以尝试相同的任务。

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

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

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

而且由于后台进程可以稍后重试,我们宁愿让它失败。

问题

我们如何在乐观锁定方法中为某些动作/参与者设置悲观锁定?

潜在的解决方案

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

  • 创建一个“用户操作”标志,该标志将在任何用户的任何操作期​​间设置
  • 在此标志为“关闭”之前,作业不会开始
  • 在任何正在运行的进程结束时,检查标志是否打开:如果是,取消此操作/回滚。

这样,进程将只能在空闲时间运行,而用户不做任何事情。

帮助

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

4

1 回答 1

1

For the "document" it is the typical case of read-write lockings.

A read-write lock works so, that multiple readers can lock the resource parallelly, but only one writer. Because of this, readers and writers are mutually exclusive.

Your real users would put a "read" lock to the document, when they start to edit. More than one of them can enter at the same time, each of them will edit a different sentence.

Your background process is the writer in this case, it can enter (by putting a "write" lock) if no readers (and no other writers) are locking this document. Then the background process can do its changes.

Also, it may happen that a user fails to open the document, but - since the background process is fast - it is very unlikely (and it's temporal, you can retry 1 sec later, even without notifying the user).

To provide you some reference, here's how you can use LockModeType.READ and LockModeType.WRITE in JPA: Read-Write lockings in JPA

于 2014-06-19T13:57:50.337 回答