chronomodel icon indicating copy to clipboard operation
chronomodel copied to clipboard

Race condition on updates in parallel with counter_cache or after_save

Open pzac opened this issue 6 years ago • 5 comments

When a record has after_save hooks (or rails built-ins such as the counter cache) that update another object, and there are parallel updates that will affect the same object, there are regular failures with timeline consistency errors. The entire callback chain should be wrapped in a transaction or have an exclusive lock on the dependent object. https://github.com/ifad/chronomodel/pull/70 has a spec to reproduce the issue

pzac avatar Mar 28 '18 15:03 pzac

Thanks for the report. Will fix asap.

vjt avatar Mar 28 '18 15:03 vjt

..or deadlocks image

pzac avatar Mar 07 '19 14:03 pzac

Sorry for the delay. The issue emerges because Active Record counter cache issues an UPDATE on the ChronoModel view, and this in turn runs the triggers for each row in your table.

This could be fixed by overriding Active Record counter cache behaviour, to issue the update on the temporal table only, but it would be another Monkey-Patch to maintain.

Further, given it is pointless to store changes to the counter cache in the history, please disable journaling on the counter cache column by using selective journaling, i.e.:

change_table :sections, temporal: true, no_journal: %w( articles_count )

I have added a section in the README to mention the requirement.

The spec is merged in b57ff400, and passes with the relevant no_journal option.

vjt avatar Apr 07 '19 22:04 vjt

Then we'd lose the purpose and benefit of the counter cache, but this was an example: the same happens when an after_save callback updates another parent object

pzac avatar Apr 08 '19 08:04 pzac

Let me check in the spec whether the no_journal breaks counter cache in the history schema.

The Callbacks problem is a completely different one, that will be researched separately.

vjt avatar Apr 08 '19 10:04 vjt