如何管理 Cosmos DB 中多次写入的会话令牌?

问题描述

我们有一个业务场景,客户端向我们发送请求,然后我们的后端服务同时插入多个文档并返回最新的 CosmosDB 会话令牌。逻辑看起来大致类似于:

// Controller Code
[HttpPost]
public async Task<IActionResult> Demo([FromBody] User[] users)
{
  // Create multiple documents here
  var tasks = new List<Task>();
  foreach(var user in users)
  {
    tasks.add(this.container.CreateItemAsync(user,new PartitionKey("my partitionKey")));
  }
  
  // task when all returns an array of ItemResponses
  ItemResponse<User> [] usersItemResponses = await Task.WhenAll(tasks); 
  
  // I Could extract the session tokens associated with each ItemResponse
  List<string> sessionTokens = usersItemResponses.Select(response => response.Headers.Session)


  // Here I would like to return the newest session token to the client side,but because the tasks were executed in parallel,I wouldn't kNow which request finished last,and therefore no way to get the latest session token.
  string sessionTokenString;
  return this.Ok(sessionTokenString);
}

但是,我找不到有关如何比较会话令牌的文档,并且我不想按顺序执行这些写入操作。

我们如何比较这些写操作的会话令牌并将最新的会话令牌返回给我们的客户端,以便他们可以在后续请求中读取数据库数据?

解决方法

您不需要自己比较会话令牌。将请求的响应标头中返回的会话令牌传递给最终用户,然后在请求选项中将其传回,以确保用户正在读取自己的写入。

查看示例,Utilize session tokens

在这里更新,因为评论太短了。

对于每个用户发送一批写入的场景,您可以自己管理会话令牌并进行比较。会话令牌的格式为

{pkrangeid}:{Version}#{GlobalLSN}#{RegionId1}={LocalLsn1}#{RegionId2}={LocalLsn2}....#{RegionIdN}={LocalLsnN}. 

但是,如果您要手动检查这一点,您基本上是在执行分布式锁,这会影响性能。如果您真正需要的是始终获取最新数据,那么您可以使用 Bounded Staleness 一致性。 BS 执行 2 个副本读取并为您比较 LSN。如果它们匹配,则数据是最新的,如果它们不匹配,则返回具有较高 LSN 的数据。由于所有写入都针对三个副本,因此您将始终获得最新数据。唯一的缺点是读取是会话一致性的 2 倍,因为它是 2 个副本读取。但是,比您建议的操作要简单得多。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...