Как при асинхронных запросах к базе сохранить последовательность?

Пример. У нас есть персонаж, которому можно наносить урон, но который восстанавливать здоровье.

Сценарий такой:
1. осталось 2 единицы здоровья
2. урон 1
3. восстановление здоровья
4. урон 1

Шаги 3 и 4 были вызваны почти одновременно, но сохранение последовательности критически влияет на исход. Предположим, что восстановление происходит по довольно сложному алгоритму, где нужно учесть много факторов. Тогда перед тем, как сохранить в базу результат, с персонажа будет списан последний хп, из-за чего он умирает и игра завершается поражением.

Важно оговорить реляционные и нереляционные базы, если между ними в этом плане есть различия.
  • Вопрос задан
  • 498 просмотров
Решения вопроса 1
goodwin332
@goodwin332
Мне кажется тебе отлично подойдёт асинхронная работа с помощью очередей.

Например rabbitmq
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
alexfilus
@alexfilus
Senior backend developer
Самое простое - 4-й запрос выполнить в колбэке 3-го.
Ответ написан
Stac
@Stac
Обычно помогает помогает простая нумерация запросов.

Например у вас есть табличка или nosql документ с условным названием hp_history - история изменения здоровья.

id| hp | action | value | timestamp
1 | 2|...|...|nnnn1
2| 1 | урон | 1 |nnn28
3| 10| лечение | 10 |nnn34
4| 9 | урон | 1 | nnn35


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

Также возможно не нужно хранить всю историю изменения здоровья, а только последнюю ее часть, текущий бой.

В критической ситуации, типа возможной смерти персонажа, стоит сделать синхронный запрос, чтобы убедиться, действительно ли он умер.
Ответ написан
@ollisso
В серверах которые я видел (lineage, ultima, rf и тп) - практически везде данные пишутся не сразу.
Т.е. обрабатываются в памяти, и пишут в базу раз в секунду, раз в 10 секунд и тп.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы