Гарантия согласованности в FaunaDB при перезаписи документа, который был прочитан в прошлом

У меня есть FaunaDB, с которой я хотел бы взаимодействовать как хранилище документов. У меня есть один API, который:

  1. Читает весь документ из FaunaDB
  2. Изменяет эти данные произвольно на основе ввода в API
  3. Пишет мутировал обратно, гарантируя, что данные не были мутированы
  4. Ошибка или повтор, если чтение не было текущим при попытке записи

В Postgres для обеспечения согласованности я бы просто использовал предложение where. Поскольку фауна распространяется, я предполагаю, что эквивалент более нюансирован, например, насколько я понимаю, записи CosmosDB идиоматически отправляют eTag чтения для проверки, чтобы гарантировать согласованность.

1 ответ

В фауне все транзакции записи проходят через конвейер транзакций в строгой сериализуемой изоляции. Таким образом, все, что нам нужно для поддержания желаемого инварианта двух наших транзакций, - это убедиться, что мы связываем нашу запись с чтением, которое проверяет, что документ не обновлялся, пока мы копались в нашем собственном коде. Позволять $ref быть какой-то ссылкой, что у нас есть магические знания. Позволять $ts быть результатом Select("ts", Get($ref)) во время нашей первоначальной транзакции чтения. Позволять $expr быть тем, чем мы хотим обновить наш документ. Затем:

If(Equals(Select("ts", Get($ref)), $ts), Update($ref, $expr), Abort("try again"))

Конечно, вы, вероятно, хотите сделать что-то умнее: возможно, лучше не возвращать обновленный документ. Как именно вы хотите структурировать это зависит от вас, но

{error: "ts out of date", updated: Get($ref)}

Работало бы достаточно хорошо, вам просто нужно было бы провести анализ полученного объекта, чтобы определить, есть ли у вас документ или произошел сбой. Вы даже можете получить все фантазии и переместить экземпляр в Let но характеристики времени выполнения практически одинаковы (чтение кэшируется локально во время eval, мы не будем делать это дважды).

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