2013-05-15 5 views
1

Внутри сеанса hash есть массив, в который я добавляю вещи. Проблема заключается в том, что иногда несколько запросов обрабатываются одновременно (потому что ajax) и изменения, которые делает запрос в массив, затем заменяются изменениями, внесенными вторым запросом.Состояние гонки с сеансами рельсов

Пример, массив первого выглядит следующим образом:

[63, 73, 92]

Тогда первый запрос добавляет что-то к нему:

[63, 73, 92, 84]

Второй запрос делает то же самое (Но работает на более старой версии, очевидно):

[63, 73, 92, 102]

Таким образом, в конце концов массив не выглядит как следует. Есть ли способ избежать этого? Я попытался использовать хранилище кэш-памяти, хранилище активных записей и хранилище файлов cookie. Такая же проблема со всеми из них.

Спасибо.

+0

Я не знаю, что еще вы делаете на стороне сервера, но как насчет HTTP: // апи .rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html – oldergod

ответ

1

В Rails действительно нет отличного решения. Мое первое предложение состояло бы в том, чтобы изучить ваш прецедент и посмотреть, можно ли вообще избежать этой ситуации. Если это безопасно, данные сеанса, если их часто лучше всего хранить на клиенте, поскольку существует ряд проблем, которые могут возникнуть при работе с хранилищами на стороне сервера. С другой стороны, если это данные, которые могут быть полезны в долгосрочной перспективе для нескольких запросов страниц (и, возможно, для нескольких сеансов), возможно, они должны поступать в базу данных.

Конечно, есть некоторые данные, которые действительно принадлежат к сеансу (хорошим примером этого является в настоящее время вошедший в систему пользователь). Если это так, посмотрите на http://paulbutcher.com/2007/05/01/race-conditions-in-rails-sessions-and-how-to-fix-them/ и, в частности, https://github.com/fcheung/smart_session_store, который пытается разобраться в ситуации, о которой вы описали.

0
  1. нагрузки на текущую сессию, или создать новый, если необходимы
  2. Сохранить копию немодифицированной сессии для дальнейшего использования
  3. Выполнить код действия
  4. Сравнить модифицированную сессию копия, сохраненная ранее, чтобы определить, что изменилось
  5. Если сеанс изменился:
    1. Заблокировать сеанс
    2. Перезагрузить сеанс
    3. Применить изменения, сделанные в этой сессии и сохранить его
    4. разблокировать сеанс

От Race conditions in Rails sessions and how to fix them.

0

Это простое условие гонки, просто заблокировать запрос с использованием любого блокирующего механизма, как redis locker

RedisLocker.new('my_ajax').run! { session[:whatever] << number } 
+0

Я думаю, что ваш замок должен быть вокруг всего запроса, чтобы это работало – Joel

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