We ran into this bug while working with a site that uses transactions extensively. The following pseudocode represents
the issue:
transaction do
my_cached_model.save
my_cached_model.destroy
end
Within a transaction, the save command will decide that it needs to store to the cache once the transaction finishes.
Trouble is, the destroy command deletes from the cache immediately... then the transaction finishes, and the cache pops
back into existence.
To truly fix this bug, the cache_delete function and the cache_store function should BOTH pop cache commands into the
delayed queue for the transaction. When the transaction finishes, the commands should be run in order, storing and
deleting as the commands need.
A really kludgy workaround that doesn't completely fix this issue is as follows:
def cache_delete
cache_local.delete cache_key_local if CachedModel.use_local_cache?
Cache.delete cache_key_memcache if CachedModel.use_memcache?
# Clean up transaction storage commands - MODIFICATION
delayed_commits = CachedModel.cache_delay_commit[CachedModel.cache_transaction_level]
unless delayed_commits.nil? then
delayed_storage_objs = delayed_commits.select {|obj| obj == self}
delayed_storage_objs.each {|obj| delayed_commits.delete(obj)}
end
end
|