Mongoid 3 中 Rails 模型的强一致性
Strong consistency for a Rails model in Mongoid 3
我希望特定模型的所有数据库交互都通过集群中的 mongo 主节点,因此我将模型设置为使用强一致性。
class Photo
include Mongoid::Document
with consistency: :strong
field :number, type: Integer
# let's say a photo number is unique in the db
validate :unique_number
end
但这似乎不起作用,因为当我保存两张非常靠近的照片时,我仍然 运行 验证错误。
photo1 # db has number=1 for this object
photo1.update_attributes(number: 2)
photo2.number = 1
photo2.save! # <= this raises a validation exception
我对强一致性的理解是这里不应该有一个race。它应该先写,然后再读,因为它都在主服务器之外,所以不应该有冲突。我错过了什么?
你所经历的好像是坚持。 update_attributes 正在对文档进行原子更改,看起来它没有更新持久化 photo1.Your photo2 验证是从持久性内部触发的(即在 rails 服务器上,而不是在 mongo) 并正在查看它拥有的记录。如果您在 photo1.update_attributes 之后 运行 photo1.reload 这可能会为您排序。
好久没用了mongoid 3, 4是state一段时间了,最近升级到5.You不会在[=22=中发现这类问题]id 4.
如果重新加载没有帮助,请输出 photo2.errors 以便我为您指出问题所在。
事实证明,在 class 级别调用 with(consistency: :strong)
只会将其应用于 下一个查询 。所以在加载class时调用class方法,为第一个查询设置强一致性,
但是后续查询不会触发相同的 class 方法,从而使它们的持久性操作以最终一致性进行操作。来自 Mongoid 3.1.7 documentation:
Tell the next persistance [sic] operation to store in a specific collection, database or session.
此方法不强制执行可以传入的持久化选项(与 class 中的其他一些方法一样),因此我们也可以传入 consistency: :strong
.
黑客修复
为了将其应用于每个*持久性操作,我将其添加到 default_scope
。
class App
default_scope -> { with(consistency: :strong); where({}) }
end
在这种情况下,默认范围期望有一个 Mongoid Criteria 对象 returned,所以我们 return 在设置一致性级别后的 noop where
子句-进度持久化操作。
* 如果开发人员决定调用 unscoped
并删除 default_scope
.
,则不会应用此选项
我希望特定模型的所有数据库交互都通过集群中的 mongo 主节点,因此我将模型设置为使用强一致性。
class Photo
include Mongoid::Document
with consistency: :strong
field :number, type: Integer
# let's say a photo number is unique in the db
validate :unique_number
end
但这似乎不起作用,因为当我保存两张非常靠近的照片时,我仍然 运行 验证错误。
photo1 # db has number=1 for this object
photo1.update_attributes(number: 2)
photo2.number = 1
photo2.save! # <= this raises a validation exception
我对强一致性的理解是这里不应该有一个race。它应该先写,然后再读,因为它都在主服务器之外,所以不应该有冲突。我错过了什么?
你所经历的好像是坚持。 update_attributes 正在对文档进行原子更改,看起来它没有更新持久化 photo1.Your photo2 验证是从持久性内部触发的(即在 rails 服务器上,而不是在 mongo) 并正在查看它拥有的记录。如果您在 photo1.update_attributes 之后 运行 photo1.reload 这可能会为您排序。
好久没用了mongoid 3, 4是state一段时间了,最近升级到5.You不会在[=22=中发现这类问题]id 4.
如果重新加载没有帮助,请输出 photo2.errors 以便我为您指出问题所在。
事实证明,在 class 级别调用 with(consistency: :strong)
只会将其应用于 下一个查询 。所以在加载class时调用class方法,为第一个查询设置强一致性,
但是后续查询不会触发相同的 class 方法,从而使它们的持久性操作以最终一致性进行操作。来自 Mongoid 3.1.7 documentation:
Tell the next persistance [sic] operation to store in a specific collection, database or session.
此方法不强制执行可以传入的持久化选项(与 class 中的其他一些方法一样),因此我们也可以传入 consistency: :strong
.
黑客修复
为了将其应用于每个*持久性操作,我将其添加到 default_scope
。
class App
default_scope -> { with(consistency: :strong); where({}) }
end
在这种情况下,默认范围期望有一个 Mongoid Criteria 对象 returned,所以我们 return 在设置一致性级别后的 noop where
子句-进度持久化操作。
* 如果开发人员决定调用 unscoped
并删除 default_scope
.