Disable query cache for lock queries #6985

Merged
merged 1 commit into from Jul 6, 2012

Projects

None yet

10 participants

@sidonath
Contributor
sidonath commented Jul 6, 2012

Query caching should be disabled for queries asking for a pessimistic lock. Otherwise the lock query may not reach the database, thus breaking the expected functionality.

Fixes #867

@rafaelfranca rafaelfranca commented on the diff Jul 6, 2012
...ve_record/connection_adapters/abstract/query_cache.rb
@@ -83,6 +83,14 @@ def cache_sql(sql, binds)
result.collect { |row| row.dup }
end
end
+
+ def locked?(arel)
+ if arel.respond_to?(:locked)
@rafaelfranca
rafaelfranca Jul 6, 2012 Member

Are there some case where locked is not defined?

@sidonath
sidonath Jul 6, 2012 Contributor

Yes, sometimes the arel is actually a String.

Without the check QueryCacheTest#test_cache_does_not_wrap_string_results_in_arrays was failing.

@rafaelfranca rafaelfranca merged commit 717aa92 into rails:master Jul 6, 2012
@jjb
Contributor
jjb commented Jul 6, 2012

@rafaelfranca - should this also be ported to the rails 3 branch?

@rafaelfranca
Member

@jjb I can backport to 3-2-stable, but I want to confirm with @tenderlove first.

@rafaelfranca
Member

@jbb done at 7adc4f2

@jjb
Contributor
jjb commented Jul 6, 2012

whoo hoo!

@nragaz
Contributor
nragaz commented Jul 27, 2012

Line 83 causes an NoMethodFound exception when there is a 'locked' scope defined on a model. The respond_to? call returns true but the method is not found.

Perhaps having a scope named 'locked' is a bad idea anyway, but that isn't documented as far as I know.

@ihoka
ihoka commented Aug 14, 2012

@nragaz Agreed on naming. Just got bitten by this when upgrading Rails. It has a weird interaction with Draper.

@steveklabnik
Member

@ihoka oh?

@ihoka
ihoka commented Aug 14, 2012

@steveklabnik yes. Draper uses method_missing and respond_to? to delegate to the model.

The issue I ran into was triggered by calling a method on the wrapped model within a decorator, which internally uses associations (has_one in my case). When doing so, it spits out an "undefined method `locked' for #Class:0x007f82fb067068", like this: https://gist.github.com/7498247d20ecd191d77e.

I spent a bunch of time chasing the cause, and finally ended up renaming my "locked" named scope to something else.

@steveklabnik
Member

Roger, okay. So not really something I could have fixed.

@nragaz
Contributor
nragaz commented Aug 14, 2012

@steveklabnik I think the point is that suddenly relying on the behaviour of a method named locked to all relations may not be so great, especially since there's no documented list of scope and class method names to avoid. It's going to cause a bunch of weird interactions, because if you redefine locked the query_cache logic is still going to call your redefined method -- and sometimes it'll even still seem to work, but mostly it won't.

@steveklabnik
Member

@nragaz in this case I'm speaking as the Draper maintainer, not as someone who works on Rails.

I agree that locked is a pretty common name to be adding to every relation.

@nragaz
Contributor
nragaz commented Aug 14, 2012

@steveklabnik Ah, cool. I didn't realize you were the Draper maintainer.

On 2012-08-14, at 1:13 PM, Steve Klabnik notifications@github.com wrote:

@nragaz in this case I'm speaking as the Draper maintainer, not as someone who works on Rails.

I agree that locked is a pretty common name to be adding to every relation.


Reply to this email directly or view it on GitHub.

@smathieu

I ran into this exact problem as well and have to rename many scopes. Would it be possible to add something similar to DangerousAttributeError for scopes?

@rafaelfranca
Member

One of the possibles solution is add a method locked? as alias to loked here and check arel.respond_to?(:locked?). But I need feedback from @tenderlove if this make sense.

@giddie
giddie commented May 2, 2013

Would be nice to get this fixed, or at least find a way to provide a slightly less obscure error message. Just got bitten by this.

@BM5k
BM5k commented Aug 19, 2013

Wasted a bunch of time on this. A better error is definitely needed :(

@grosser grosser commented on the diff Oct 25, 2013
...ve_record/connection_adapters/abstract/query_cache.rb
@@ -83,6 +83,14 @@ def cache_sql(sql, binds)
result.collect { |row| row.dup }
end
end
+
+ def locked?(arel)
+ if arel.respond_to?(:locked)
+ arel.locked
@grosser
grosser Oct 25, 2013 Contributor

FYI we have a scope called locked and this is blowing up ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment