Скажем, у меня есть следующие сущности и отношения:Проверка ActiveRecord заблокирована в состоянии «Обновление»
A<-B<-C<-D<-E
У меня есть много Е для того же А (Е принадлежит А через D, C и B)
у меня есть фрагмент кода, который выглядит следующим образом:
eList=E.all
varA=eList.first.D.C.B.A
E.transaction do
...Operations that take some time...
varA.update_attributes(::last_update=>Time.now)
end
Теперь думаю, что этот фрагмент кода работает с потоками. Один поток на объект E. Это означает, что если у меня 10 E для одного A, 10 потоков будут запускать в то же время этот фрагмент.
Мои проблемы приходит с линией
varA.update_attributes(:last_update=>Time.now)
Когда я смотрю на мой код, я вижу, что у меня есть это:
[DEBUG] 2013/02/13 13:09:51 [66222] - abstract_adapter.rb:198 - A Update (3107.1ms) UPDATE "A" SET "updated_at" = '2013-02-13 13:09:47.932899', "last_update" = '2013-02-13 13:09:47.932209' WHERE "id" = 144
[DEBUG] 2013/02/13 13:09:54 [48600] - abstract_adapter.rb:198 - A Update (6812.2ms) UPDATE "A" SET "updated_at" = '2013-02-13 13:09:47.218032', "last_update" = '2013-02-13 13:09:47.217421' WHERE "id" = 144
[DEBUG] 2013/02/13 13:09:56 [66190] - abstract_adapter.rb:198 - A Update (6717.5ms) UPDATE "A" SET "updated_at" = '2013-02-13 13:09:49.328496', "last_update" = '2013-02-13 13:09:49.327777' WHERE "id" = 144
[DEBUG] 2013/02/13 13:09:59 [66219] - abstract_adapter.rb:198 - A Update (10816.2ms) UPDATE "A" SET "updated_at" = '2013-02-13 13:09:48.236539', "last_update" = '2013-02-13 13:09:48.235895' WHERE "id" = 144
[DEBUG] 2013/02/13 13:10:01 [66200] - abstract_adapter.rb:198 - A Update (13450.9ms) UPDATE "A" SET "updated_at" = '2013-02-13 13:09:47.584182', "last_update" = '2013-02-13 13:09:47.583467' WHERE "id" = 144
Как вы можете видеть, время выполнения каждого увеличения запросов для каждого потока. Первый занимает 3 секунды, а последний занимает 13. Я предполагаю, что это потому, что я обновляю одну и ту же запись (A.id = 144), поэтому запись заблокирована, а остальные потоки должны ждать.
Мой вопрос в том, есть ли способ в Rails 2.3, что я могу определить, заблокирована ли запись, потому что она обновляется, поэтому я могу просто заставить другие потоки пропускать обновление?
Что-то вроде:
if not varA.locked then varA.update_attributes(:last_update=>Time.now) end
Это достаточно хорошо для меня, чтобы обновить только один раз, так что я хочу, чтобы другие потоки, чтобы проверить, если он уже обновляя и двигаться дальше.
FWIW, моя БД Postgres 9,0