Как вносить изменения в базу последовательно, т.е. выстраивать в очередь в определенном моменте?

Привет!


В общем, работаем сейчас над системой где есть рейтинг, есть пользователи.


Все пользователи влияют на рейтинг. Однако, если в один и тот же момент два пользователя совершили действие которое меняет рейтинг, засчитают только один, потому как времени которое проходит между считыванием с базы актуального рейтинга и обновлением достаточно много.


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


Поскажите, буду очень благодарен.
  • Вопрос задан
  • 3169 просмотров
Решения вопроса 1
dali
@dali
эм. вы что делаете SELECT rating FROM users WHERE userid = :id, потом делаете rating++, потом делаете UPDATE users SET rating=:rating WHERE userid=:id? Во-первых, вы можете просто делать UPDATE users SET rating=rating+1 WHERE userid=:userid. Во-вторых, можете выстроить очередь. При изменении рейтинга в очередь ложить действие (+ или -), :userid, потом обработчик очереди сам сделает + или — над рейтингом очереди, но тогда пользователь не увидит мгновенного изменения рейтинга. В-третьих можно рейтинги пользователей держать в кэше, делать +- в кэше, показывать из кэша, а кэш синхронизировать с базой несколько раз в день или по какому-нибудь событию.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
Urvin
@Urvin
Не хотите вынести код инкремента или декремента рейтинга в процедуру типа incrementRating(@userId)?
Ответ написан
g0lden
@g0lden
У вас есть таблица в базе, в ней некое поле с текущим «рейтингом», происходит какое-то событие из-за которого значение поля «рейтинг» должно измениться (стать n++ или по какому-то другому принципу), и если таких событий происходит единовременно несколько то на «рейтинг» повлияет только одно?

Если так то можно выстраивать события, которые повлияли на рейтинг, в буфер, затем вычислять суммарное влияние всего буфер на «рейтинг» и уже используя эту некую сумму влияний от всех событий из буфера, накладывать на текущий «рейтинг», ну и соответственно пока это происходит накапливать новый буфер.

з.ы.
Если хотите более точного ответа уточняйте вопрос.
Ответ написан
Комментировать
knekrasov
@knekrasov
Есть подозрение, что вы не используете транзакции.

1. В mysql есть SELECT… FOR UPDATE
2. Почему бы не использовать UPDATE… rating = rating + 1 как выше советовал dali
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы