Andreas Gebhard 的回答中指向ActiveRecord::Locking::Optimistic的链接从技术上说你需要知道的一切。但是,如果我为您拼写出来,可能会更清楚。
如果您lock_version
在表中添加一个名为的字段,默认情况下 ActiveRecord 将启用乐观锁定。但是,您还没有完成。
您遇到的问题称为“丢失的更新问题”,即第二个人的更新破坏了之前个人的更新。如果您所做的只是在数据库层中启用乐观锁定,如果您正常编程并且不采取必要的步骤,您的 Web 应用程序仍然会出现丢失更新问题。
通常,您的更新操作会查找记录,然后将所有字段替换为从表单发送的值。就数据库和 ActiveRecord 所知,您从最近的一条新记录开始并对其进行了更新。因此乐观锁定将满足于允许更新,但您仍然有丢失更新的问题。
您需要做的是将该lock_version
字段作为隐藏输入包含在您的表单中。然后当第二个更新的人尝试更新时,将 lock_version 设置为之前更新完成之前的旧值将导致乐观锁定失败。
在悲观锁中,避免丢失更新问题的关键是获取编辑表单必须首先获取锁。如果其他人将其锁定,您将无法编辑。解决丢失更新问题的一个非常重要的关键是循环中的人,通过在编辑之前呈现数据库中的值,这样只有人才能决定更改它们。在丢失的更新中,有人不知道其他人的更新,因此保存了先前的值而不知道它已被更新。
实际上,问题没有解决办法。总会有人输的。在丢失更新问题中,第一个保存的人会失败。在悲观(又名排他锁)中,第二个尝试获得锁的人会失败。在乐观锁定第二个人保存失败。
悲观/排他锁定的缺点是有人试图获取编辑表单被拒绝,因为其他人拥有锁定。此外,锁可能不会在应该释放的时候被释放,并且您可能会遇到死锁。
乐观锁定的缺点是有人可以在编辑时完成所有工作,但在尝试保存时会被拒绝。
无论如何,对于试图编辑的人来说,这都是一个惊喜。丢失更新问题的缺点是最糟糕的情况是惊喜悄然发生,没有人注意到。至少通过排他或乐观锁定,用户会得到通知。使用乐观锁定,他们必须“合并”,可能不得不从新数据开始重做他们的编辑工作。使用独占锁定,他们永远不会遇到这个问题,但他们可能不得不等待并且可能不明白为什么。乐观锁定的普遍偏好是,大多数时候没有更新争用,它只是工作,而对于独占锁定,总是需要进入编辑模式并刷新编辑表单上的数据。