我的环境是ASP.NET Core 2.x使用.NET SDK访问CosmosDb(也就是DocumentDb)。
我的集合的默认一致性级别设置为“Session”。对于我的用例,我需要一个经过身份验证的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 App服务器有一个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或当前有多少其他用户使用该数据库。
提前致谢!
答案 0 :(得分:0)
我想这里的困惑在于会话是什么?
在大多数情况下/框架将会话视为静态标识符(相关性),其中,与cosmos一样,sessionToken是动态的(cosmos db状态的书签/表示形式,随写入而变化)。将其命名为“sessionToken”可能是混乱的根源。
在这种特定情况下,您应该使用cosmos API中的“返回的会话结构”。