简体   繁体   English

在覆盖过去读取的文档时保证FaunaDB的一致性

[英]Guaranteeing consistency in FaunaDB when overwriting a document that was read in the past

I have a FaunaDB which I would like to interact with as a document store. 我有一个FaunaDB,我想与文档存储进行交互。 I have a single api which: 我有一个api:

  1. Reads an entire document from FaunaDB 从FaunaDB读取整个文档
  2. Mutates that data arbitrarily based on input to the api 根据对api的输入任意改变数据
  3. Writes the mutated back while guaranteeing the data has not been mutated 写入变异的同时保证数据没有被变异
  4. Error or retry if the read was not current when attempting to write 如果在尝试写入时读取不是当前的错误或重试

In Postgres to guarantee consistency I would simply use a where clause. 在Postgres中为了保证一致性,我只想使用where子句。 Since Fauna is distributed I assume the equivalent is more nuanced, for example my understanding is that CosmosDB writes idiomatically send the eTag of the read to check to guarantee consistency. 由于Fauna是分布式的,我假设等价物更细致,例如我的理解是CosmosDB惯用地写入读取的eTag来检查以保证一致性。

In fauna all write transactions run through the transaction pipeline at strict serializable isolation. 在动物群中,所有写入事务都以严格的可序列化隔离在事务管道中运行。 So all we need to maintain the desired invariant over our two transactions is to make sure we tie our write to a read that checks that the document hasn't been updated while we were futzing around in our own code. 因此,我们需要在两个事务中保持所需的不变量,以确保我们将写入绑定到一个读取,该读取检查在我们自己的代码中进行预测时文档尚未更新。 Let $ref be some ref that we have magical knowledge of. $ref成为我们有神奇知识的参考。 Let $ts be the result of Select("ts", Get($ref)) during our original read transaction. 在我们的原始读取事务期间Select("ts", Get($ref))$ts成为Select("ts", Get($ref)) Let $expr be whatever we want to update our document to. $expr成为我们想要更新文档的任何内容。 Then: 然后:

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

Of course, you probably want to do something smarter: It's probably a better idea on failure to return the updated document. 当然,您可能希望更聪明地做一些事情:如果未能返回更新的文档,这可能是一个更好的主意。 Exactly how you want to structure that is up to you but 究竟你想要如何构建由你决定的但是

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

Would work well enough, you'd just need some case analysis in on the resulting object to see if you had the doc or a failure. 如果工作得很好,你只需要对结果对象进行一些案例分析,看看你是否有文档或失败。 You could even get all fancy and move the instance read into a Let but the runtime characteristics are much the same (the read is cached locally during eval, we won't do it twice). 您甚至可以获得所有想象力并将实例读取移动到Let但运行时特性大致相同(读取在eval期间在本地缓存,我们不会执行两次)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM