我在企业应用程序中使用 mongodb,对于某些用例,我必须使用事务。
一开始我似乎没有正确使用 mongodb 的
ClientSession
。每次我尝试启动交易时,我也会启动一个会话,但结果证明这是一个错误。当我使用多个并发请求测试应用程序时,我遇到了WriteConflict
错误,这显然意味着我在两个单独的会话上的单个集合上执行并发事务。
所以现在看来,对于我们应用程序的每个租户,我都需要有一个预先创建的会话,并且任何时候我想要执行事务时,我都只需使用现有的会话。但似乎一个会话上只能有一个活动事务,这意味着我还需要为我的事务维护一个队列,以便在上一个事务完成并且会话空闲时我可以立即执行下一个事务。但这会使应用程序的某些部分变得非常慢。
所以我的问题是,这种方法是否有任何替代方案,以便我可以使用事务,但也能够同时响应请求,这样我就不会受到性能损失?
谢谢
WriteConflict 错误与会话数量无关,而是与尝试同时更新同一文档的多个事件有关。
在事务中,数据修改是暂存的,然后在事务提交时立即应用。 如果事务要修改的文档之一已更改,则事务代码无法确定您是否希望该修改包含在事务中或被事务覆盖,因此它会抛出 WriteConflict,以便您的应用程序代码可以决定如何处理。 这就是 WriteConflict 错误包含文本“请重试您的操作或多文档事务。”的原因。
如果您有多个交易都试图修改同一个文档,就像柜台一样,它们将必须轮流。
您可以为每个事务使用单独的会话,这样就不需要查询,而不是为每个租户预先创建一个会话并对事务进行排队。 或者也许使用分片(取决于用例)。 使用分片按租户隔离数据。每个租户的数据都驻留在单独的分片上,从而减少争用。 不同分片上的交易可以同时运行而不会发生冲突。