【发布时间】:2018-11-03 03:46:14
【问题描述】:
我的环境是 ASP.NET Core 2.x 使用 .NET SDK 访问 CosmosDb(又名 DocumentDb)。
我的收藏的默认一致性级别设置为“会话”。对于我的用例,我需要一个经过身份验证的 Web 用户在 Web 请求之间的读/写方面始终拥有一致的数据。
我有一些 CosmosDB 存储库逻辑,通过 ASP.NET Core Singleton 依赖注入可用于我的控制器逻辑:
services.AddSingleton<DocumentDBRepository, DocumentDBRepository>(x =>
new DocumentDBRepository(
WebUtil.GetMachineConfig("DOCDB_ENDPOINT", Configuration),
WebUtil.GetMachineConfig("DOCDB_KEY", Configuration),
WebUtil.GetMachineConfig("DOCDB_DB", Configuration),
"MyCollection",
maxDocDbCons));
DocumentDBRespository 像这样创建一个 cosmos 客户端:
public DocumentDBRepository(string endpoint, string authkey, string database, string collection, int maxConnections)
{
_Collection = collection;
_DatabaseId = database;
_Client = new DocumentClient(new Uri(endpoint), authkey,
new ConnectionPolicy()
{
MaxConnectionLimit = maxConnections,
ConnectionMode = ConnectionMode.Direct,
ConnectionProtocol = Protocol.Tcp,
RetryOptions = new RetryOptions()
{
MaxRetryAttemptsOnThrottledRequests = 10
}
});
_Client.OpenAsync().Wait();
CreateDatabaseIfNotExistsAsync().Wait();
CreateCollectionIfNotExistsAsync().Wait();
}
据我了解,这意味着每个 Web 应用服务器一个 CosmosDB 客户端。我确实有多个 Web 应用服务器,因此单个用户可能会从多个 AppServer 和不同的 CosmosDb 客户端访问 CosmosDB。
在用户与 ComosDB 交互之前,我会检查他们的会话对象是否有 CosmosDb SessionToken,如下所示:
string docDbSessionToken = HttpContext.Session.GetString("StorageSessionToken");
然后,例如,在编写文档时,该方法看起来像这样:
public async Task<Document> CreateItemAsync<T>(T item, Ref<string> sessionTokenOut, string sessionTokenIn = null)
{
ResourceResponse<Document> response = null;
if (string.IsNullOrEmpty(sessionTokenIn))
{
response = await _Client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(_DatabaseId, _Collection), item);
}
else
{
response = await _Client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(_DatabaseId, _Collection), item, new RequestOptions() { SessionToken = sessionTokenIn });
}
sessionTokenOut.Value = response.SessionToken;
Document created = response.Resource;
return created;
}
这个想法是,如果我们有一个会话令牌,我们传递一个并使用它。如果我们没有,只需创建文档,然后将新创建的会话令牌返回给调用者。这工作正常...
除了,我不清楚为什么当我传递一个会话令牌时,我会得到一个不同的会话令牌。也就是说,当_Client.CreateDocumentAsync返回时,response.SessionToken总是和参数sessionTokenIn不同。
这是否意味着我应该从那时起为该用户使用新的会话令牌?这是否意味着我应该忽略新的会话令牌并使用初始会话令牌?
其中一个“会话”能持续多久?它们是传统意义上的会话吗?
最终,我只需要确保同一用户始终可以读取他们的写入内容,无论他们连接到哪个 AppServer 或当前有多少其他用户正在使用数据库。
【问题讨论】:
-
我知道这是一个老问题,但我想知道您是否曾经得到过这个问题的答案?
-
这能回答你的问题吗? Session Consistency and the .NET Client SDK
-
赞成 Q 和 A,因为两者都很棒,但这是一个重复,在stackoverflow.com/a/37060289/11635 中得到了很好的回答
标签: asp.net-core azure-cosmosdb