Skip to content

GraphQL 多重变更

GraphQL 的多重变更允许在一个请求中执行多个变更操作,减少网络往返次数。数据墙DBW 支持在一次 mutation 中组合多个创建、更新或删除操作。

IMPORTANT

多重变更仅 SQL Server 支持,且只在 GraphQL 中可用。

配置启用

多重创建变更默认关闭,需要在运行时中显式启用:

json
{
  "runtime": {
    "graphql": {
      "multiple-mutations": {
        "create": {
          "enabled": true
        }
      }
    }
  }
}
bash
dab configure --runtime.graphql.multiple-mutations.create.enabled true

更新和删除的批量操作不需要额外配置,直接可用。

多重创建

启用后,create{Entity}item 参数变为 items(复数),接受对象数组:

graphql
mutation {
  createBooks(
    items: [
      { id: 101, title: "第一本", year: 2024, pages: 280 }
      { id: 102, title: "第二本", year: 2024, pages: 320 }
      { id: 103, title: "第三本", year: 2024, pages: 150 }
    ]
  ) {
    items { id title }
  }
}

批量创建需要对每个主键有唯一值,且所有记录的字段结构一致。响应返回创建的全部记录:

json
{
  "data": {
    "createBooks": {
      "items": [
        { "id": 101, "title": "第一本" },
        { "id": 102, "title": "第二本" },
        { "id": 103, "title": "第三本" }
      ]
    }
  }
}

multiple-mutations.create.enabledfalse(默认)时,只能使用单条 item

graphql
mutation {
  createBook(item: { id: 101, title: "单本" }) { id title }
}

同一变更中的多重操作

可以在一个 mutation 请求中同时执行不同实体的操作:

graphql
mutation {
  createBook(item: { id: 200, title: "新书" }) { id title }
  updateAuthor(id: 10, item: { lastName: "更新后的姓" }) { id lastName }
  deleteBook(id: 99) { id }
}

多个操作按顺序依次执行。如果某个操作失败,已执行的操作不会回滚——GraphQL 多重变更不支持事务。

指向同一实体的多重操作

可以使用别名在同一请求中对同一实体执行多个操作:

graphql
mutation {
  book1: createBook(item: { id: 301, title: "第一本" }) { id title }
  book2: createBook(item: { id: 302, title: "第二本" }) { id title }
  book3: updateBook(id: 300, item: { title: "更新后的书名" }) { id title }
}

别名是必需的——同名字段在 GraphQL 中必须用别名区分。响应中各结果按别名区分:

json
{
  "data": {
    "book1": { "id": 301, "title": "第一本" },
    "book2": { "id": 302, "title": "第二本" },
    "book3": { "id": 300, "title": "更新后的书名" }
  }
}

部分成功处理

多重变更中某个操作失败时,成功的操作仍返回数据,失败的操作返回错误:

json
{
  "data": {
    "createBook": { "id": 101, "title": "第一本" },
    "deleteBook": null
  },
  "errors": [
    {
      "message": "Could not find item with the given key.",
      "path": ["deleteBook"]
    }
  ]
}

客户端需要分别检查 dataerrors 来确认每个操作的结果。

数据库要求

多重变更需要数据库支持多活动结果集(MARS)。SQL Server 用户请确保连接字符串包含:

text
MultipleActiveResultSets=True

如果连接池配置了 Pooling=FalseMultipleActiveResultSets=False,多重变更可能失败并报错 Implicit distributed transactions have not been enabled

变量形式

复杂变更推荐使用变量分离:

graphql
mutation BatchCreate(
  $item1: CreateBookInput!
  $item2: CreateBookInput!
) {
  book1: createBook(item: $item1) { id title }
  book2: createBook(item: $item2) { id title }
}
json
{
  "variables": {
    "item1": { "id": 101, "title": "第一本" },
    "item2": { "id": 102, "title": "第二本" }
  }
}

变量形式代码更清晰,且避免了字符串拼接带来的安全问题。

使用建议

场景使用方式
批量导入相同结构的数据createXxxs(items: [...])
一次提交多个不同操作同一 mutation 中组合 + 别名
前端表单提交相关数据组合关联实体的创建
需要事务保证不要用多重变更——在存储过程中封装事务逻辑

限制

  • 仅 SQL Server 支持多重变更。
  • 不支持事务——操作按顺序执行但不回滚。
  • multiple-mutations.create.enabled 默认关闭,需显式启用。
  • 需要 MARS 启用。

下一步

数据墙DBW 产品文档与开发指南。