2009-08-21 52 views
1

我在使用ActiveRecord和Rails使用sqlite的情況下(也是,這是JRuby,所以我實際上使用jdbcsqlite適配器,以防萬一)。現在,我試圖在表中插入一行attention_seekers,但前提是沒有其他類似的行。因此,如何確保sqlite不緩存特定的選擇查詢?

unless AttentionSeeker.find(:first, :conditions => {:key_id => key.id, :locale_id => l.id}) 
    item = AttentionSeeker.new(:key_id => key.id, :locale_id => l.id) 
    item.save 
end 

這是在日誌中生成的輸出:

CACHE (0.0ms) SELECT * FROM attention_seekers WHERE (attention_seekers.key_id = 318 AND attention_seekers.locale_id = 20) 
AttentionSeeker Create (1.0ms) INSERT INTO attention_seekers (key_id, locale_id) VALUES(318, 20) 
CACHE (0.0ms) SELECT * FROM attention_seekers WHERE (attention_seekers.key_id = 318 AND attention_seekers.locale_id = 20) 
AttentionSeeker Create (2.0ms) INSERT INTO attention_seekers (key_id, locale_id) VALUES(318, 20) 

正如你所看到的,由於某種原因,找到的是被緩存,即使我將影響它的元素。我在做什麼錯了/我該如何阻止這種行爲?

回答

3

我做了一些挖掘並碰到了this helpful blog post,有更多信息可用here。我的解決方案(使用麥克Buckbee建議的驗證 - 謝謝!):

AttentionSeeker.uncached do 
    item = AttentionSeeker.new(:key_id => key.id, :locale_id => l.id) 
    item.save 
end 
+0

真棒喬希,很高興你明白了。 – 2009-08-21 20:59:49

1

而是把你的控制器代碼(這是我猜它是),你可能想使用確認,而不是,我認爲會解決這個問題需要考慮:

class AttentionSeeker < ActiveRecord::Base 
    validates_uniqueness_of :key_id, :scope => :locale_id 
end 

請請注意驗證規則中的「範圍」選項。

如果做不到這一點,你可以嘗試在Transaction

做不到這包裹查詢,這似乎令人難以置信的janky你可以緩存無效化添加到查詢本身。類似於

buster = rand(Time.now) 
attention_seeker = AttentionSeeker.find(:first, :conditions => ["#{buster} = #{buster}"]) 

哪一個應該給你一個獨特的查詢,每次通過你的循環。

+0

我很興奮地嘗試這一點,但我看到完全一樣的行爲。 – 2009-08-21 20:05:18

+0

您是否嘗試在交易中包裝它? (我的第二個建議) – 2009-08-21 20:21:33

+0

我在交易中將上面的代碼片段包裹起來,但沒有任何變化。 – 2009-08-21 20:25:02