Rails how to touch Active Record Object without locking? Rails how to touch Active Record Object without locking? ruby-on-rails ruby-on-rails

Rails how to touch Active Record Object without locking?


That's an issue I stumbled upon myself, too.

Short answer: There is no easy way around this problem. All the touches are wrapped in the same transaction, hence the deadlock.

Long answer: I am guessing you need touch objects to invalidate some sort of (dependent) caches. The usually recommended use of touch only works for a limited amount of "relationships". E.g. invalidating the article when the comment is being updated.

My solution was the asynchronous collection (using a sidekiq job) of DB Objects that need to be invalidated. I wrote my own control logic for it that defines what (other) objects need to be invalidated when an object changed. E.g. comment ==> article.

This way we had a way more verbose way invalidating dependent objects. Plus I invalidated using an Model.update_all which was way faster then the "touch chain". It solved our deadlock problems (and added verbosity and performance to our cache invalidation).

Extra tip: Don't use updated_at. It's highly debatable if a DB object really changed because another object changed. Overwriting the cache_key model lets you easily define a custom cache key like "#{id}-#{valid_from}". valid_from could be a timestamp you define on your models (and that you use instead of updated_at).