-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Turn off ActiveRecord caching within lock blocks #52
Comments
I also asked for input from the Rails team at rails/rails#43634. I thought they might be able to provide some guidance based on how ActiveRecord deals with this in row-level locking (if at all). |
My 2 cents on this. I had the exact same problem as described in #47 and adding a |
+1 for this |
(I'm too rusty with Rails at this point to give an opinion: this seems like an innocuous enough change, but either way, the documentation should be updated to highlight this issue. @seuros would you accept a PR with this change, if @jmanian or @lucasprag or @muxcmux submitted one?) |
Yes. |
Any news on this RFC ? I'm planning in releasing a new version pretty soon. I dropped old version of rails/ruby, so this implementation should be easier now. |
@seuros I've rolled out a PR which adds that option to |
I explained this issue in depth in #47. The short version is that ActiveRecord caching can lead to stale query results within an advisory lock, at a time when it's critical to be working with up-to-date data.
I'm thinking that it may make sense for the
with_advisory_lock
block to automatically turn off caching viaActiveRecord::QueryCache.uncached
for the duration of the block. Or perhaps there should be an argument towith_advisory_lock
to control this.The example use case is using an advisory lock to prevent the double-creation of a record. Take this for example:
In this example users are created from 3rd party webhooks, and the goal is to create a new user if it doesn't already exist, or update the existing one.
The problem I ran into is that upstream of the lock in my code I had a
User.find_by(external_id: external_user.id)
. The user didn't exist at this point, so the result was being cached asnil
. Then inside the lockfind_or_initialize_by
used the cached result ofnil
, even though by this time the user record had already been created, thus defeating the purpose of the lock.I solve this in my code by using
uncached
to ensure a fresh query:The text was updated successfully, but these errors were encountered: