You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We've encountered a situation where the cache isn't expired if, within a transaction, a model has a "non-update" followed by an update. Here's the code that created a stale cache in our application:
defupdate_user(id,attributes)# hashApplicationRecord.transactiondoUser.find(id).update(attributes.except(:email))update_sign_in_information(id,attributes[:email])endenddefupdate_sign_in_information(user_id,email)user=User.find(user_id)user.update(email: email)# other stuffend
If only the email attribute is passed in, this leads to a stale cache. Here are some more examples that demonstrate the bug:
classTesterdefself.testresetApplicationRecord.transactiondouser=User.firstuser.update({})user.update(name: "test2")endputs"###### user name: #{User.fetch(User.first.id).name}"# test2, goodresetApplicationRecord.transactiondoUser.first.update({})User.first.update(name: "test2")endputs"###### user name: #{User.fetch(User.first.id).name}"# test1, staleresetApplicationRecord.transactiondoUser.first.update(name: "test1")User.first.update(name: "test2")endputs"###### user name: #{User.fetch(User.first.id).name}"# test1, staleenddefself.resetUser.first.update(name: "test1")User.fetch(User.first.id)# fill the cacheendend
A similar "bug" exists in ActiveRecord:
classUser < ApplicationRecordafter_commit:print_namedefprint_nameputsuser.nameendendApplicationRecord.transactiondoUser.first.update(name: "test1")User.first.update(name: "test2")end# prints test1 after the whole transaction is committed
The bug goes pretty deep and seems to involve the activerecord and ar_transaction_changes gems. Essentially, the @transaction_changed_attributes variable that IdentityCache's _run_commit_callbacks method is checking is attached to the record, but the after_commit callback is only being called on the first instance even if the transaction contains multiple updates. Here's the monkey patch my team is currently considering adding to address the issue, but could lead to performance regressions:
def_run_commit_callbacks# if destroyed? || transaction_changed_attributes.present?expire_cache# endsuperend
The text was updated successfully, but these errors were encountered:
We've encountered a situation where the cache isn't expired if, within a transaction, a model has a "non-update" followed by an update. Here's the code that created a stale cache in our application:
If only the
email
attribute is passed in, this leads to a stale cache. Here are some more examples that demonstrate the bug:A similar "bug" exists in ActiveRecord:
The bug goes pretty deep and seems to involve the
activerecord
andar_transaction_changes
gems. Essentially, the@transaction_changed_attributes
variable that IdentityCache's_run_commit_callbacks
method is checking is attached to the record, but theafter_commit
callback is only being called on the first instance even if the transaction contains multiple updates. Here's the monkey patch my team is currently considering adding to address the issue, but could lead to performance regressions:The text was updated successfully, but these errors were encountered: