首页 > 解决方案 > 我可以在一个请求中运行多个动物数据库事务吗?

问题描述

可以让 Fauna 使用Do. 但是,它在这种特殊情况下不起作用:

Do(
  CreateCollection({ name: "users" }),
  CreateIndex({
    name: "users_by_email",
    permissions: { read: "public" },
    source: Collection("users"),
    terms: [{field: ["data", "email"]}],
    unique: true
  }) 
)

我认为这是因为“索引 [...] 可能不会在与其源集合相同的事务中创建。” https://docs.fauna.com/fauna/current/api/fql/functions/createindex?lang=javascript

如何在一个请求中有效地同时提交我的集合和索引创建命令?

标签: faunadb

解决方案


直接回答标题问题:不。一个“请求”是一个交易。

但是,正如您所指出的,可以在单个事务中执行多个 FQL 表达式,例如您对Do函数的使用。

Do函数不适用于您的示例的原因是 Fauna 查询执行器在评估事务表达式时执行读取和聚合写入意图,但所有写入效果都发生在事务结束时。CreateIndex这意味着在评估您的表达式时该集合尚未完全写入,因此Collection("users")在需要时不存在。

这就是文档中存在警告的原因。您需要在一个事务中创建集合,并在另一个事务中创建索引。如果您要部署已知模式,则可以在单个事务中创建所有集合,并在一秒钟内创建所有索引。这是最佳实践答案。

但是,目前 API v4 可以通过使用以下Let函数来完成这项工作:

Let(
  {
     collection: CreateCollection({ name: "users" }),
     collection_ref: Select("ref", Var("collection")),
  },
  CreateIndex({
    name: "users_by_email",
    source: Var("collection_ref"),
    terms: [{field: ["data", "email"]}],
    unique: true,
  })
)

这样做的原因是source索引的字段需要有效的引用。通过CreateCollection在命名变量中捕获结果,可以CreateIndex通过变量在表达式中使用引用。

source将来,查询执行器可能会升级,以验证字段中变量提供的所有引用的合法性。如果/当这种情况发生时,这种技术将不再有效。使用此技术需要您自担风险


推荐阅读