Возможно ли и является ли хорошей практикой предоставление клиентской версии DynamoDb Optimisti c Locking для предотвращения гонки на более высоком уровне? - PullRequest
0 голосов
/ 05 марта 2020

Вот общая проблема состояния гонки

  1. Ресурс создан со списком
  2. ServiceA и ServiceB хотят добавить что-то в список в Resource
    1. ServiceA получает Ресурс (list = [])
    2. ServiceB получает ресурс (list = [])
    3. ServiceA обновляет ресурс (list = [A]) и успешно
    4. ServiceB обновляет ресурс ( list = [B]) и успешно

Ожидается: ресурс (список = [A, B]) или исключение

Факт: ресурс (список = [B]) И что еще хуже, это тихая ошибка

С помощью DynamoDB Optimisti c Блокировка с номером версии , мы можем решить эту проблему, и сценарий выглядит следующим образом.

  1. Ресурс создается со списком (и версия = 1)
  2. ServiceA и ServiceB хотят добавить что-то в список внутри ресурса
    1. ServiceA получает ресурс (list = [] , версия = 1)
    2. ServiceB получает ресурс (список = [], версия = 1)
    3. ServiceA обновляет ресурс (l ist = [A], версия = 1) и успешно (версия становится 2)
    4. ServiceB обновляет ресурс (список = [B], версия = 1) и завершается ошибкой, потому что версия отстает

Таким образом, ServiceB уведомляется о сбое и может решить повторить попытку, повторно загрузив Ресурс (с версией = 2 и списком = [A]) и обновив Ресурс (список = [A, B] , версия = 2).

DynamoDB управляет версией для вас. При создании ресурса он устанавливает значение 1, автоматически увеличивает его при каждом обновлении и создает исключение, если версии не совпадают.

У меня вопрос, можно ли выставлять эту версию клиенты во время их запросов Get (предполагая, что клиент - это не наш код, а какой-то другой сервис, принадлежащий нашей организации) и позволяют им предоставлять его во время запросов на обновление?

  • Первая часть вопрос в том, возможно ли это технически?
  • Вторая часть вопроса - это хорошая практика? (ie. Есть ли проблемы с этим, даже если мы технически можем?)

1 Ответ

2 голосов
/ 05 марта 2020

Во-первых, у DynamoDB на самом деле нет концепции управления версиями записи. Эта концепция вводится некоторыми библиотеками, которые добавляют поле версии и используют Условные выражения при вызове PutItem. Таким образом, в этом отношении вы на самом деле не выставляете значение DynamoDB, вы выставляете значение, которое вы выбрали для добавления к своим данным (хотя и с помощью SDK).

Во-вторых, вполне возможно, что быть лучшим подходом к этому. Попробуйте использовать UpdateItem и воспользоваться некоторыми из более продвинутых UpdateExpressions , в частности операцией ADD.

Если существующий тип данных является набором и если значение также является набором, то значение добавляется к существующему набору. Например, если значением атрибута является набор [1,2] и задано действие ADD [3], то окончательное значение атрибута - [1,2,3]. Ошибка возникает, если для атрибута набора задано действие ADD, а указанный тип атрибута не соответствует существующему типу набора.

Это может позволить вам выполнить частичные обновления и не беспокоиться о нескольких запросах изменяя те же данные. У него есть свои пределы, но в вашем точном сценарии я считаю, что это сработает.

...