我需要执行事务(BEGIN、COMMIT或ROLLBACK)、锁定(SELECT FOR UPDATE). 如何在文档模型数据库中执行此操作?

编辑:

情况是这样的:

  • 我想经营一个拍卖网站.
  • 我也在想如何直接购买.
  • 在直接采购中,我必须减少项目记录中的数量字段,但只有在数量大于零的情况下.这就是我需要锁和事务的原因.
  • 如果没有锁和/或事务,我不知道如何解决这个问题.

我可以用CouchDB解决这个问题吗?

推荐答案

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

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

Keeping track of inventory

您概述的问题主要是库存问题.如果您有一个描述项目的文档,并且其中包含一个用于表示可用数量的字段,则您可以按如下方式处理并发问题:

  1. 检索文档,注意CouchDB发送的_rev属性
  2. 如果数量字段大于零,则将其递减
  3. 使用_rev属性将更新后的文档发回
  4. 如果_rev与当前存储的号码匹配,则完成!
  5. 如果存在冲突(当_rev不匹配时),请检索最新的文档版本

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

现在,我刚才给出的答案假定您将在CouchDB中以与在RDBMS中大致相同的方式进行操作.我可能会以不同的方式来处理这个问题:

我会从包含所有描述符数据(名称、图片、描述、价格等)的"主产品"文档开始.然后,我将 for each 特定实例添加一个"库存票据"文档,其字段分别为product_keyclaimed_by.如果您在销售一个型号的锤子,并且有20个要出售,那么您可能会有一些文档,其中包含hammer-1hammer-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

Database相关问答推荐

是否可以同时从 RocksDB 读取?

如何在 Big Data 中进行模糊搜索

PostgreSQL 嵌套 INSERTs / WITHs 用于外键插入

如何在 SQL Server 中将索引从一个表复制到另一个表

我应该为 Realm 中的每个实体定义主键吗?

哪个本地数据库适合 Windows 8 应用store 应用?

group by会自动保证order by吗?

如何在 VS 2012 的 SQL Server 数据库项目中存储静态数据

SQLite 中内存数据库的优势

关系数据库如何在幕后工作?

B+ 树相对于 BST 的优势?

在 SQL 数据库之间共享数据

MySQL相对于其他数据库的缺点

Sqlite 判断表是否为空

cURL 和 PHP 显示1

Google 的 Bigtable 与关系数据库

复式记账的关系数据模型

Rake aborted... table ‘users’ already exists

最佳事件采购数据库策略

使用命令行在 Mysql 中导入压缩文件