我希望多个用户能够同时在网络浏览器中编辑模型,并在保存时检测到冲突(这样第一个写入的用户不会在没有第二个用户明确表示的情况下覆盖他们的更改)。这是示例:
用户 A 检索对象 X 并在他们的浏览器中查看它。
然后用户 B 检索对象 X,在他们的浏览器中查看它,对其进行修改,然后将其保存,从而将其发布到 Grails 中的 REST apisave
并将模型上的 a 发布到数据库。
然后用户 A 修改并保存该对象。
我希望应用程序检测到对象 X 在用户 A 检索到它后已被修改,并且我将向用户 A 显示一条合适的消息,其中包含一些选项。
我如何知道模型是否已更改?请注意,这isDirty
将不起作用,save(flush:true)
也不会起作用。
更新
我看到一些关于 Optimistic Locking 和检测模型更改的答案,因为它已提交。我想检测更改,因为它是由用户检索的。请再次阅读问题。
在这里我将澄清为什么乐观锁定不能解决上述问题。但是,我可以想象可能有一种方法可以让我使用乐观锁定,但是正如下面的答案和文档中所描述的那样,它无济于事。这就是为什么。
乐观锁定在请求中起作用,而不是跨请求。如果第二个用户在第一个用户的更新请求正在进行时更新了一个对象,那么乐观锁定将只允许一个用户执行更新。乐观锁定可防止在同一请求中读取-修改-写入与另一个读取-修改-写入交错。这是乐观锁定所防止的事件的时间线(时间从上到下):
User 1 User 2
presses submit presses submit
in update action
| read model
| in update action
| | read model
| | modify model
| | write model
| return
| modify model
| write model - FAILS
return error or something
由第一个用户发布的模型写入失败,因为乐观锁定检查检测到记录在被读取后被修改。
我想防止的是以下时间表:
User 1 User 2
visits web app visits web app
clicks link to edit model clicks link to edit model
in edit action
| read model
| render model
return
in edit action
| read model
| render model
return
user edits model user edits model
user thinks... hmm... user submits
in update action
| read model
| modify model from params
| write model
return
user submits
in update action
| read model
| modify model from params
| write model - OOPS! overwrote previous changes
return
从这个示例中,您可以看到用户 1 覆盖了用户 2 的更改。但是用户 1 根据数据库中模型的旧副本进行了更改,如果她在思考时看到用户 2 的更改,她可能会做一些不同的事情。