Strong Rails Model Consistency in Mongoid 3

I want all my interactions with db for a particular model to go through the main mongo in my cluster, so I have set strong consistency for the model.

class Photo include Mongoid::Document with consistency: :strong field :number, type: Integer # let say a photo number is unique in the db validate :unique_number end 

But this does not work, because I still encounter validation errors when I save two Photo photos very close to each other.

 photo1 # db has number=1 for this object photo1.update_attributes(number: 2) photo2.number = 1 photo2.save! # <= this raises a validation exception 

My understanding of strong consistency is that there should not be a race. He must write and then read, and since all this comes from the primary, there should be no conflict. What am I missing?

+6
source share
2 answers

It turns out that calling with(consistency: :strong) at the class level will only apply it to the next request . Therefore, the class method is called when the class is loaded, establishing strong consistency for the first request, but subsequent requests do not start the same class method, leaving their continuity operations to work with a possible sequence. From Mongoid 3.1.7 documentation :

Tell us about the next [sic] operation to save to a specific collection, database, or session.

This method does not apply persistence parameters that can be passed (for example, several other methods in the class), so we can also pass consistency: :strong .

Hack fix

To apply this to every save operation *, I added it to default_scope .

 class App default_scope -> { with(consistency: :strong); where({}) } end 

In this case, the default region expects the Mongoid Criteria object to return, so we return the noop where clause after setting the level of consistency in the continue operation.

* This will not apply if the developer decides to call unscoped and disable default_scope .

0
source

What you experience in the area seems like perseverance. An atomic change to the document is made in the update_attributes file, and it does not appear to update the saved photo. Your photo2 validation is launched from within the persistence (that is, on the rails server, and not in mongo) and looks at the records there. If you started photo1.reload after photo1.update_attributes, this may sort this out for you.

Some time has passed since I used mongoid 3, 4 being the main product for some time and recently updated to 5. You will not find this type of problem in mongoid 4.

If the reboot does not help, please print photo2.errors so that I can indicate that the problem is for you.

0
source

All Articles