chronomodel
chronomodel copied to clipboard
Race condition on updates in parallel with counter_cache or after_save
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
Thanks for the report. Will fix asap.
..or deadlocks
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.
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
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.