Как правильно составить игровую сделку «Купить/Продать предмет»

Я работаю над функциональностью «Купить/Продать предмет» для ролевой игры. Если я прав, следующие действия должны выполняться в одной транзакции.

  1. Получить игрока на основе playerID из таблицы «Игроки»
  2. Проверьте, достаточно ли у игрока золота, если да, создайте новый объект предмета.
  3. Запишите новый объект элемента в таблицу «Элементы», где владелец основан на pllayerID
  4. Обновите строку таблицы «Игроки», где владельцем является playerID, вычтите золото в зависимости от стоимости предмета.

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

Я прочитал документы и вижу, что в DynamoDB есть TransactWriteItems и TransactGetItems, которые кажутся идеальными для этого, но они разные. Могу ли я как-то использовать их в одной транзакции?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Получив playerID, вы сможете объединить шаг 4 с шагом 2, а затем выполнить шаги 2-3 в одном TransactWriteItems:

  1. UPDATE стоимость золота условно - если имеется достаточно золота, немедленно вычтите стоимость предмета, в противном случае условие не выполняется, как и TransactWriteItems.
  2. Если вы сделали это здесь, золота было достаточно, и вы можете создать и записать новый объект в таблицу Items.

Изменить для объяснения того, почему это работает:

TransactWriteItems группирует действия "Обновить золото" и "положить предмет" как одно целое операция «все или ничего»: либо они оба успешны, либо они оба терпят неудачу. И если другая операция мешает, они также обе терпят неудачу (без состояния гонки).

Например:

  • Если золота недостаточно, обновление завершается ошибкой, поэтому добавление предмета также завершается ошибкой.
  • Если добавление предмета не удается, изменения, внесенные в золото, не сохранятся (обновление «не сработает»)
  • Если другая операция изменяет количество золота, обе операции завершатся ошибкой.

Принципиально невозможно:

  1. вычесть золото, но не добавить предмет
  2. добавить предмет, но не вычесть золото

Поскольку они оба находятся в рамках операции TransactWriteItems, происходят либо оба, либо ни один из них.

Вы можете найти пример на Java здесь. (В вашем случае вы можете просто отказаться от проверки клиента и изменить «обновление статуса продукта» на «обновление золота игрока» и «добавить заказ» на «добавить элемент».)

Подробнее см. TransactWriteItems документацию здесь.

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

Ilja 30.12.2020 14:34

Я отредактировал ответ с объяснением атомарности TransactWriteItems и ссылкой на пример. Надеюсь, это поможет, дайте мне знать, если что-то все еще не ясно.

sigma1510 30.12.2020 18:55

Другие вопросы по теме