Azure Cosmos DB 中的事务性批处理操作

适用范围: NoSQL

事务性批处理描述了一组需要一起成功或失败且在容器中具有相同分区键的点操作。 定义操作、添加到批处理中并执行批处理。 如果所有操作都按照事务性批处理操作中描述的顺序成功完成,则会提交事务。 但是,如果任何操作失败,则会回滚整个事务。

什么是 Azure Cosmos DB 中的事务

典型数据库中的事务可以定义为一系列作为工作的单个逻辑单元执行的操作。 每个事务都提供 ACID(原子性、一致性、隔离性、持久性)属性保证。

  • 原子性保证将一个事务内部执行的所有操作视为一个单位,这些操作要么全部提交,要么都不提交。
  • 一致性确保数据始终在各个事务之间处于有效状态。
  • 隔离性保证不会存在两个事务互相干扰的情况 � 许多商务系统提供多个可以基于应用程序需求使用的隔离级别。
  • 持久性确保数据库中提交的任何更改始终存在。 对于同一逻辑分区键内的操作,Azure Cosmos DB 支持具有快照隔离功能的完全符合 ACID 的事务

事务性批处理操作与存储过程

Azure Cosmos DB 当前支持存储过程,这些存储过程也提供了操作的事务作用域。 但是,事务性批处理操作具有以下优势:

  • 语言选项 � 你使用的 SDK 和语言支持事务性批处理,而存储过程需要使用 JavaScript 进行编写。
  • 代码版本控制 � 对应用程序代码进行版本控制,并将其加入到 CI/CD 管道,这比对存储过程的更新进行协调并确保在恰当的时间进行滚动更新要自然得多。 使用此功能,对更改进行回滚也变得更加容易。
  • 性能 � 与存储过程执行相比,将等效操作的延迟降低了高达 30%
  • 内容序列化 � 事务性批处理中的每个操作都可以使用其有效负载的自定义序列化选项。

如何创建事务性批处理操作

创建事务性批处理操作时,请从容器实例开始并调用 CreateTransactionalBatch

PartitionKey partitionKey = new PartitionKey("road-bikes");

TransactionalBatch batch = container.CreateTransactionalBatch(partitionKey);

接下来,将多个操作添加到批处理:

Product bike = new (
    id: "68719520766",
    category: "road-bikes",
    name: "Chropen Road Bike"
);

batch.CreateItem<Product>(bike);

Part part = new (
    id: "68719519885",
    category: "road-bikes",
    name: "Tronosuros Tire",
    productId: bike.id
);

batch.CreateItem<Part>(part);

最后,对批处理调用 ExecuteAsync

using TransactionalBatchResponse response = await batch.ExecuteAsync();

收到响应后,检查响应是否成功。 如果响应指示成功,请提取结果:

if (response.IsSuccessStatusCode)
{
    TransactionalBatchOperationResult<Product> productResponse;
    productResponse = response.GetOperationResultAtIndex<Product>(0);
    Product productResult = productResponse.Resource;

    TransactionalBatchOperationResult<Part> partResponse;
    partResponse = response.GetOperationResultAtIndex<Part>(1);
    Part partResult = partResponse.Resource;
}

重要

如果失败,则失败的操作会有其相应错误的状态代码。 其他所有操作都会有 424 状态代码(失败的依赖项)。 如果操作因尝试创建已存在的项而失败,则返回状态代码 409 (冲突)。 可通过状态代码查明导致事务失败的原因。