我需要执行事务(BEGIN、COMMIT或ROLLBACK)、锁定(SELECT FOR UPDATE). 如何在文档模型数据库中执行此操作?
编辑:
情况是这样的:
- 我想经营一个拍卖网站.
- 我也在想如何直接购买.
- 在直接采购中,我必须减少项目记录中的数量字段,但只有在数量大于零的情况下.这就是我需要锁和事务的原因.
- 如果没有锁和/或事务,我不知道如何解决这个问题.
我可以用CouchDB解决这个问题吗?
我需要执行事务(BEGIN、COMMIT或ROLLBACK)、锁定(SELECT FOR UPDATE). 如何在文档模型数据库中执行此操作?
编辑:
情况是这样的:
我可以用CouchDB解决这个问题吗?
不是的.CouchDB使用"乐观并发"模型.最简单地说,这只是意味着随更新一起发送文档版本,如果当前文档版本与您发送的文档版本不匹配,CouchDB将拒绝更改.
这看起来很简单,真的.您可以为CouchDB重新构造许多基于事务的正常场景.不过,在学习CouchDB时,你确实需要抛弃你的RDBMS领域知识.从更高的层次处理问题,而不是试图将coach塑造成一个基于SQL的世界,这是很有帮助的.
Keeping track of inventory
您概述的问题主要是库存问题.如果您有一个描述项目的文档,并且其中包含一个用于表示可用数量的字段,则您可以按如下方式处理并发问题:
_rev
属性_rev
属性将更新后的文档发回_rev
与当前存储的号码匹配,则完成!_rev
不匹配时),请检索最新的文档版本在这种情况下,有两种可能的失败场景需要考虑.如果最新的文档版本的数量为0,您可以像在RDBMS中一样处理它,并提醒用户他们实际上无法购买他们想要购买的东西.如果最新文档版本的数量大于0,只需使用更新的数据重复该操作,然后从头开始.这会迫使您比RDBMS做更多的工作,如果更新频繁且相互冲突,可能会有点烦人.
现在,我刚才给出的答案假定您将在CouchDB中以与在RDBMS中大致相同的方式进行操作.我可能会以不同的方式来处理这个问题:
我会从包含所有描述符数据(名称、图片、描述、价格等)的"主产品"文档开始.然后,我将 for each 特定实例添加一个"库存票据"文档,其字段分别为product_key
和claimed_by
.如果您在销售一个型号的锤子,并且有20个要出售,那么您可能会有一些文档,其中包含hammer-1
、hammer-2
等关键字来表示每个可用的锤子.
然后,我将创建一个视图,该视图给我一个可用锤子的列表,该视图带有一个Reduce函数,让我可以看到"总数".这些完全是即兴的,但应该会让您了解工作视图是什么样子.
Map个
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
件商品的总数,因此您可以知道有多少"锤子"可供购买.
Caveats个
这个解决方案代表了对你提出的特定问题大约3.5分钟的总体思考.也许有更好的方法可以做到这一点!这就是说,它确实大大减少了冲突的更新,并减少了用新的更新来应对冲突的需要.在这种模式下,不会有多个用户试图更改初级产品条目中的数据.在最糟糕的情况下,你会有多个用户试图申领一张罚单,如果你从你的视图中抓取了几张,你只需转到下一张罚单,然后再试一次.
参考文献:https://wiki.apache.org/couchdb/Frequently_asked_questions#How_do_I_use_transactions_with_CouchDB.3F