Как убедиться, что sqlite не кэширует определенные запросы на выборку? - PullRequest
1 голос
/ 21 августа 2009

Я нахожусь в ситуации, когда я использую sqlite с ActiveRecord и Rails (также это JRuby, и поэтому на самом деле я использую адаптер jdbcsqlite, в случае, если это важно). Сейчас я пытаюсь вставить строку в таблицу Внимание_Секеры, но только если другой существующей аналогичной строки не существует. Соответственно,

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 ]

3 голосов
/ 22 августа 2009

Я немного покопался и наткнулся на этот полезный пост в блоге , с более подробной информацией здесь . Мое решение (используя проверку, предложенную Майком Бакби - спасибо!):

AttentionSeeker.uncached do
  item = AttentionSeeker.new(:key_id => key.id, :locale_id => l.id)
  item.save
end
1 голос
/ 21 августа 2009

Вместо того, чтобы помещать этот код в свой контроллер (что, как я предполагаю, есть), вы можете вместо этого рассмотреть возможность использования проверки, что, я думаю, решит проблему:

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

Обратите внимание на параметр «область действия» в правиле проверки.

Если вы не можете попытаться обернуть запрос в транзакцию

Если это не удастся, и это кажется невероятно рискованным, вы можете добавить кешбастер к самому запросу. Что-то вроде

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

Который должен давать вам уникальный запрос каждый раз через ваш цикл.

0 голосов
/ 12 декабря 2009

Уникальные индексы на уровне схемы безопаснее, чем validates_uniqueness_of.

См. http://railswarts.blogspot.com/2007/11/validatesuniquenessof-is-broken-and.html

Stephan

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...