【问题标题】:Couchdb locking documents on bulk update批量更新时 Couchdb 锁定文档
【发布时间】:2017-02-08 02:03:31
【问题描述】:

有没有办法在执行批量保存时在 Couchdb 中创建锁?我相信没有内置的方法可以实现这一点,但是是否可以通过解决方法来解决这个问题?我有一个类似于以下的场景(我使用 Node.js 与 couchdb 数据库交互):

用户支付另一个用户创建一个新的文档对象如下:

{
    _id: SOMEID
    type: "PAYMENT"
    username: SOMEUSER
    paidto: ANOTHERUSER
    amount: 10
}

保存后,我还需要更新用户在他/她的account document 中的余额(从他/她的钱包中减去 10)。然后我使用 bulk_docs 一次保存这两个文档(新创建的transaction document 和更新的account document)。

但是,如果在此过程中用户通过其他方法(假设在另一个选项卡中)对account document 进行了更改,我们会遇到新的transaction document 被保存而account document 无法更新的问题。这会产生一个大问题和一致性问题。

为了解决这个问题,我们必须锁定account document,直到批量保存过程结束,在此期间第二个选项卡中的过程等待锁定被释放。

我正在尝试部署 Couchdb 是一个文档之间的一致性非常重要但没有锁的环境,这变得非常困难。

【问题讨论】:

    标签: couchdb


    【解决方案1】:

    保存后,我还需要更新用户在他/她的帐户文档中的余额(从他/她的钱包中减去 10)。

    不要。银行业务是用于文档数据库的very well documented example。最佳做法是仅将交易存储为文档,并将账户余额视为对(由账户索引的交易的)视图的查询。

    地图

    function(o) {
      if (o.paidto && o.amount && o.username) {
        emit(o.paidto, o.amount);
        emit(o.username, -o.amount);
      }
    }
    

    减少

    _sum
    

    查询

    GET /mydb/_design/mydesign/_view/myview/?group=true&key=SOMEUSER
    

    【讨论】:

    • 是的,但是你将如何解决竞争条件?假设您的花费不能超过您拥有的,即总数不能为负数。目前你的钱包里有 20 美元。现在让我们假设两个“支出”过程同时开始,每次抽取 20 美元。他们会检查钱包里有多少,然后开始消费。如果第二个进程检查并完成交易,而第一个进程刚刚检查并即将完成交易,第一个进程可能导致钱包变为负-20$?
    • @pewpewlasers 好问题。我的第一个想法是模仿它可能在银行中完成的方式:创建了交易,但随后发送了无效命令。例如,您可以使用NodeJS process listening to _changes API 执行此操作,请求查看以获取相应用户的帐户余额,并在超出透支限制时发送无效命令(特殊文档)。
    • 谢谢你的建议,我会试试你的方法。
    猜你喜欢
    • 2022-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多