我有一个 FaunaDB,我想与它作为文档存储进行交互。我有一个 api,它:
- 从 FaunaDB 读取整个文档
- 根据对 api 的输入任意改变数据
- 在保证数据没有被变异的同时写回变异的数据
- 如果在尝试写入时读取不是当前的,则错误或重试
在 Postgres 中,为了保证一致性,我会简单地使用 where 子句。由于 Fauna 是分布式的,我假设等价物更加细微,例如,我的理解是 CosmosDB 写入惯用地发送读取的 eTag 以检查以保证一致性。
我有一个 FaunaDB,我想与它作为文档存储进行交互。我有一个 api,它:
在 Postgres 中,为了保证一致性,我会简单地使用 where 子句。由于 Fauna 是分布式的,我假设等价物更加细微,例如,我的理解是 CosmosDB 写入惯用地发送读取的 eTag 以检查以保证一致性。
在动物群中,所有写入事务都以严格的可序列化隔离通过事务管道运行。因此,我们需要在两个事务中保持所需的不变量,就是确保我们将写入与读取联系起来,以检查文档是否在我们自己的代码中被更新时没有更新。让我们$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)}
工作得很好,你只需要对结果对象进行一些案例分析,看看你是否有文档或失败。您甚至可以花很多心思将实例读取移动到 aLet
中,但运行时特性几乎相同(读取在 eval 期间本地缓存,我们不会这样做两次)。