如何用MongoDB转钱?

时间:2013-11-22 12:33:54

标签: mongodb transactions locking

Account has embedded
  Transactions
    amount (positive for received transactions, negative for outgoing transactions)

用户想要汇款。我们需要计算账户余额以检查是否有足够的资金。在伪代码中:

send_money(amount)
  balance = sum(account's all transactions) // Mongo Query 1
  if (amount <= balance)
    add a new transaction to account // Mongo Query 2

但两个并发的mongo连接是否都可以通过查询1并继续进行查询2?假设用户的余额为1,并且两个并发的1个发送货币请求同时通过查询1并成功添加到交易中。实际上,用户最终得到-1的余额。

这是如何防止的?

3 个答案:

答案 0 :(得分:2)

当您的用例需要跨多个文档的事务时,MongoDB通常不适合它,因为当多个文档受到影响时它不支持原子操作。

可能的解决方法是two-phase-commit模型。

它基本上意味着您首先将描述要添加的内容添加到每个文档作为附加字段。然后对应用该操作的每个文档执行原子操作并删除描述。这些步骤中的每一步都通过随后查询文档得到确认,并且事务的每个步骤都由另一个待处理事务集合中的第三个文档记录。这允许您检查待处理的事务并将其回滚。

这种方法很难实现,并且开销很大。在实现之前,您应该考虑是否有充分的理由不使用具有本机事务支持的数据库系统。

答案 1 :(得分:1)

如何使用此处概述的Update If Current模式:http://docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations/可能在该页面底部附近讨论了“在每次更新操作时为应用程序增加的文档添加版本变量”的建议?除了事务数组之外,您可能还需要跟踪文档中字段中的当前余额。因此,您的更新部分可能需要在您的版本字段中输入$ inc为1,在余额字段中为$ inc的$ inc,以及为数组中的新事务元素$ push。

答案 2 :(得分:0)

这将不再是明年夏天以后的问题。 MongoDB将在4.0版中添加对多文档事务的支持,因此我们将在RBDMS系统中的多文档事务中提供ACID保证。

现在,MongoDB用例将适合所有可以使用的用户!

查看此帖子:https://www.mongodb.com/blog/post/multi-document-transactions-in-mongodb?jmp=community