首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我可以在CouchDB中进行事务和锁定吗?

我可以在CouchDB中进行事务和锁定吗?
EN

Stack Overflow用户
提问于 2008-11-18 18:46:24
回答 7查看 31.1K关注 0票数 82

我需要做事务(begin、commit或rollback)、锁(select for update)。如何在文档模型db中执行此操作?

编辑:

情况是这样的:

  • 我想运行一个拍卖网站。
  • 和我想如何直接购买。
  • 在直接购买中,我必须减少项目记录中的数量字段,但只有在数量大于零的情况下。这就是为什么我需要锁,而没有锁和/或事务,transactions.
  • I不知道如何解决这个问题。

我能用CouchDB解决这个问题吗?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2008-11-18 18:51:24

不是的。CouchDB使用“乐观并发”模型。最简单地说,这只是意味着您将文档版本与更新一起发送,如果当前文档版本与您发送的版本不匹配,CouchDB将拒绝更改。

这看起来很简单,真的。您可以为CouchDB重新构建许多常规的基于事务的场景。不过,在学习CouchDB时,您确实需要丢弃您的RDBMS领域知识。从更高的层次解决问题是有帮助的,而不是试图将Couch塑造成一个基于SQL的世界。

跟踪库存

您概述的问题主要是库存问题。如果您有一个描述项目的文档,并且其中包含一个“可用数量”字段,那么您可以像这样处理并发问题:

  1. 检索文档,注意_rev属性CouchDB发送给quantity字段,如果大于零
  2. 将更新的文档发回,使用_rev属性
  3. 如果_rev与当前存储的数字匹配,则执行操作!<代码>H213<代码>H114如果存在冲突(当<代码>D15不匹配时),请检索最新的文档版本<代码>H216<代码>G217

在这种情况下,有两种可能的故障情况需要考虑。如果最新文档版本的数量为0,您可以像在RDBMS中一样处理它,并警告用户他们实际上无法购买他们想要购买的东西。如果最新文档版本的数量大于0,则只需使用更新后的数据重复该操作,然后从头开始。这迫使您比RDBMS做更多的工作,如果有频繁的、冲突的更新,可能会有一点恼人。

现在,我刚才给出的答案假设您将在CouchDB中以与在关系型数据库管理系统中相同的方式进行操作。我可能会以不同的方式来处理这个问题:

我会从一个包含所有描述符数据(名称、图片、描述、价格等)的“主产品”文档开始。然后,我将为每个特定实例添加一个“库存票据”文档,其中包含product_keyclaimed_by字段。如果您正在销售一个锤子模型,并且有20个这样的模型可供销售,那么您可能会有一些文档,其中包含hammer-1hammer-2等关键字来表示每个可用的锤子。

然后,我将创建一个视图,该视图给我一个可用锤子的列表,该视图具有一个reduce函数,让我可以看到“总数”。这些完全是即兴的,但应该会让你对一个工作视图有一个概念。

地图

function(doc) 
{ 
    if (doc.type == 'inventory_ticket' && doc.claimed_by == null ) { 
        emit(doc.product_key, { 'inventory_ticket' :doc.id, '_rev' : doc._rev }); 
    } 
}

这为我提供了一个按产品密钥列出的可用“票证”列表。当有人想买锤子时,我可以抓取一组这样的东西,然后迭代发送更新(使用id_rev),直到我成功地认领了一个(之前认领的票证将导致更新错误)。

Reduce

function (keys, values, combine) {
    return values.length;
}

这个reduce函数只返回无人认领的inventory_ticket商品的总数,因此您可以知道有多少“锤子”可供购买。

警告

这个解决方案代表了您所提出的特定问题大约3.5分钟的总思考时间。也许有更好的方法可以做到这一点!也就是说,它确实大大减少了冲突的更新,并减少了用新的更新来响应冲突的需要。在此模型下,不会有多个用户尝试更改主要产品条目中的数据。在最坏的情况下,您将有多个用户试图申请一个票证,如果您从视图中获取了其中的几个票证,则只需转到下一个票证并重试。

参考:https://wiki.apache.org/couchdb/Frequently_asked_questions#How_do_I_use_transactions_with_CouchDB.3F

票数 149
EN

Stack Overflow用户

发布于 2008-11-25 10:02:12

对库尔特先生的回答进行扩展。在许多情况下,您不需要按顺序赎回股票。您可以从剩余的票证中随机选择,而不是选择第一张票证。假设有大量的票证和大量的并发请求,与每个人都试图获得第一张票证相比,您将大大减少对这些票证的争用。

票数 27
EN

Stack Overflow用户

发布于 2009-07-31 23:02:00

restfull事务的设计模式是在系统中创建一种“张力”。对于银行帐户事务的流行示例用例,您必须确保更新涉及的两个帐户的合计:

  • 创建一个交易单据“将10美元从帐户11223转到帐户88733”。这在系统中造成了紧张。
  • 解决所有交易单据的任何紧张扫描,
    • 如果源账户尚未更新,则更新源账户(-10美元)
    • 如果源账户已更新,但交易文档未显示此信息,则更新交易单据(例如,在文档中设置标志"sourcedone“)
    • 如果目标账户未更新,则更新目标账户(+10美元)

    <代码>H111如果目标账户已更新,但交易文档未显示此信息,则更新the transaction document

    • 如果两个账户都已更新,则可以删除交易单据或将其保留以备更新

对于所有“张力文档”,应在后端过程中扫描张力,以保持系统中的张力时间较短。在上面的示例中,当第一个帐户已经更新,但第二个帐户尚未更新时,将会出现短时间的预期不一致。必须考虑到这一点,就像处理分布式Couchdb的最终一致性一样。

另一种可能的实现完全避免了对事务的需要:只需存储the文档,并通过评估每个涉及到的the文档来评估系统的状态。在上面的示例中,这意味着帐户的合计仅确定为涉及此帐户的事务文档中的总和值。在Couchdb中,您可以很好地将其建模为map/reduce视图。

票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/299723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档