2

Скажем, у меня есть следующие сущности и отношения:Проверка 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

ответ

0

Проверка, является ли строка заблокирована для обновления является относительно сложной процедуры в PostgreSQL, и, насколько я могу сказать выполнимо только на процедурных языках, которые могут нештатных ловушки SQL. Я был бы очень удивлен, если бы ActiveRecord мог это сделать.

Если вам нужно это сделать, вам, вероятно, потребуется написать хранимые процедуры, которые улавливают эти исключения и переходят на SQL.

 Смежные вопросы

  • Нет связанных вопросов^_^