在 C# 异步代码中使用 MongoDB 客户端会话和事务是不是安全?
Posted
技术标签:
【中文标题】在 C# 异步代码中使用 MongoDB 客户端会话和事务是不是安全?【英文标题】:Is it safe to use MongoDB ClientSessions & Transactions in C# async code?在 C# 异步代码中使用 MongoDB 客户端会话和事务是否安全? 【发布时间】:2019-01-21 05:01:23 【问题描述】:来自文档Read isolation consistency - Sessions(强调我的)
为了提供因果一致性,MongoDB 3.6 在客户端会话中启用了因果一致性。因果一致的会话表示相关联的读取和确认写入操作序列具有因果关系,这反映在它们的顺序上。 应用程序必须确保一次只有一个线程在客户端会话中执行这些操作。
来自文档Transactions - Transactions & Sessions
事务与会话相关联。也就是说,您为会话启动事务。在任何给定时间,您最多可以为一个会话打开一个事务。
这是否表明使用 async/await 是不安全的,或者至少所有使用会话和事务的任务都应该(以某种方式)在同一个线程上执行?
还是说会话上的每个异步操作都需要完成才能启动另一个操作?
或者说可以针对会话运行多个异步操作,但所有这些操作必须在同一个线程上运行。
tl;dr在事务中使用 async/await 是否安全? 如果不是,这里的最佳做法是什么?
例如这(诚然可怕的代码)好吗?
[HttpPost]
public async Task<IActionResult> PostAsync(CreateRequest createRequest)
using (var session = await _client.StartSessionAsync())
await session.StartTransactionAsync();
var inserts = new Task[]
_colHomer.InsertOneAsync(session, createRequest.Homer),
_colMarge.InsertOneAsync(session, createRequest.Marge),
_colBart.InsertOneAsync(session, createRequest.Bart)
;
await Task.WhenAll(inserts);
await session.CommitTransactionAsync();
【问题讨论】:
我们正在使用异步交易,但到目前为止我们还没有发现任何问题,您有什么问题吗?即使它也没有在该文件中引起关注.. 看起来不错(异步 + 事务),但我们还没有投入生产,甚至还没有进行正确的负载测试。如果有问题我会在这里发布。 到目前为止,您在使用 mongo 时遇到过任何问题吗? @MarekM。到目前为止还没有,但同样,没有使用生产级别的数据或并发事务。另外,我已经离开了那个项目,不再与它联系。 【参考方案1】:事务和会话是designed 是不是线程安全的。我认为上面的代码会起作用,但不能保证适用于所有情况。 更新:但是以常规异步方式使用会话/事务绝对可以节省(无需任何手动任务等待和类似逻辑)。
【讨论】:
以上是关于在 C# 异步代码中使用 MongoDB 客户端会话和事务是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章