Что делать, если транзакция не удалась? - PullRequest
0 голосов
/ 05 сентября 2018

Итак, в основном есть игра, в которой вы владеете планетой, отправляете корабли на другие планеты, и через некоторое время вы можете владеть этой новой планетой.

PlanetB подвергается нападению с кораблем:

[PlanetA] ----> [PlanetB]

Процесс прибытия судна при завоевании PlanetB следующий:

  • Предыдущий владелец PlanetB должен вернуть деньги владельцу PlanetA (одна транзакция в дБ T0)
  • Теперь владелец PlanetA должен создать новый депозит (одна транзакция в дБ T1)
  • Только если предыдущая транзакция прошла успешно, мы можем изменить владельца PlanetB на владельца PlanetA

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

В основном деньги и депозиты хранятся в базе данных, поскольку они важны (на сервере A), но игровые планеты и корабли находятся в памяти (на сервере B).

Итак, вопросы:

  • Что делать, если T0 не работает из-за ошибки базы данных, например, я получаю слишком много ошибок соединения.? Я мог бы проигнорировать это, но это не хорошо, потому что владелец PlanetA не получит деньги новой принадлежащей планеты.

  • То же самое для T1, транзакция завершается неудачно из-за какой-то странной ошибки соединения с БД. Игрок даже не получит свою планету. Нужно будет отправить еще один корабль, чтобы повторить попытку, что не оптимально.

Я должен повторять это снова и снова, до тех пор, пока он не сможет остановить этот корабль на долгое время.

1 Ответ

0 голосов
/ 19 сентября 2018

Я думаю, что нет простого ответа. Все, что звучит как система БД, немного перегружено и должно быть настроено так, чтобы выдерживать большую нагрузку. Тогда все зависит от того, насколько последовательным ты хочешь быть. Моей первой идеей было бы разгрузить данные в какое-то другое хранилище до того, как база данных будет готова, а затем сохранить там данные. Вы можете добавить некоторого брокера обмена сообщениями (например, zeromq), который, возможно, способен принимать немного данных, а затем в фоновом режиме (например, в пакетах) загружать данные в базу данных. Или вы можете сделать что-то подобное, сохранив данные в случае недоступной базы данных в файл (журнал) на сервере B. И попытавшись сохранить данные в базе данных, когда это возможно. Имейте в виду, что это «решение» делает ваши изменения данных в конечном итоге непротиворечивыми. Я имею в виду, если есть какие-то выгруженные данные, например, в журнале, и вы запрашиваете базу данных, они не могут быть сохранены, и пользователь может наблюдать другое состояние данных в этот момент времени.

...