CouchDB/Couchbase/MongoDB事务仿真? [英] CouchDB/Couchbase/MongoDB transaction emulation?

查看:156
本文介绍了CouchDB/Couchbase/MongoDB事务仿真?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以前从未使用过CouchDB/MongoDB/Couchbase,并且正在为我的应用程序对其进行评估.一般来说,它们似乎是我想使用的非常有趣的技术.但是,出于RDBMS的背景,我对缺少事务感到很困惑.但是同时,我知道,鉴于数据的组织方式,与RDBMS中的交易相比,交易的需求将大大减少.

I've never used CouchDB/MongoDB/Couchbase before and am evaluating them for my application. Generally speaking, they seem to be a very interesting technology that I would like to use. However, coming from an RDBMS background, I am hung up on the lack of transactions. But at the same time, I know that there is going to be much less a need for transactions as I would have in an RDBMS given the way data is organized.

话虽这么说,但我有以下要求,不确定是否/如何使用NoSQL DB.

That being said, I have the following requirement and not sure if/how I can use a NoSQL DB.

  1. 我有一个客户清单
  2. 每个客户端可以有多个文件
  3. 每个文件必须是该特定客户端的顺序编号

鉴于RDBMS,这将非常简单.一个用于客户端的表,一个(或多个)文件的表.在客户表中,保留最后一个文件号的计数器,并在将新记录插入文件表时加一.将所有内容包装在交易中,可以确保您有不一致之处.哎呀,为了安全起见,我什至可以对(clientId,filenumber)索引施加唯一约束,以确保不会有相同的文件编号用于两次客户端.

Given an RDBMS this would be fairly simple. One table for client, one (or more) for files. In the client table, keep a counter of last filenumber, and increment by one when inserting a new record into the file table. Wrap everything in a transaction and you are assured that there are inconsistencies. Heck, just to be safe, I could even put a unique constraint on a (clientId, filenumber) index to ensure that there is never the same filenumber used twice for a client.

如何在MongoDB或CouchDB/base中完成类似的工作?可行吗?我一直在阅读有关两阶段提交的内容,但似乎无法围绕这种情况在这种情况下的工作进行总结.在Spring/Java中,有什么东西可以提供适用于这些DB的两阶段提交,还是需要使用自定义代码?

How can I accomplish something similar in MongoDB or CouchDB/base? Is it even feasible? I keep reading about two-phase commits, but I can't seem to wrap my head around how that works in this kind of instance. Is there anything in Spring/Java that provides two-phase commit that would work with these DBs, or does it need to be custom code?

推荐答案

默认情况下,Couchdb是事务性的. ouchdb中的每个文档都包含一个_rev键.使用此_rev键对文档进行所有更新:-

Couchdb is transactional by default. Every document in couchdb contains a _rev key. All updates to a document are performed against this _rev key:-

  1. 获取文档.
  2. 使用_rev属性将其发送以进行更新.
  3. 如果更新成功,则您已更新了文档的最新_rev
  4. 如果更新失败,则文档不是最新的.重复步骤1-3.

查看 MrKurt的答案以了解更多信息详细说明.

Check out this answer by MrKurt for a more detailed explanation.

couchdb收据的银行示例显示了交易的完成方式在couchdb中.

The couchdb recipies has a banking example that show how transactions are done in couchdb.

还有原子银行转帐文章,介绍了ouchdb中的交易.

And there is also this atomic bank transfers article that illustrate transactions in couchdb.

无论如何,所有这些链接中的共同主题是,如果遵循针对_rev进行更新的ouchdb模式,则数据库中不会出现不一致的状态.

Anyway the common theme in all of these links is that if you follow the couchdb pattern of updating against a _rev you can't have an inconsistent state in your database.

为了安全起见,我什至可以对(clientId,filenumber)索引施加唯一约束,以确保永远不会为客户端使用相同的文件号两次.

Heck, just to be safe, I could even put a unique constraint on a (clientId, filenumber) index to ensure that there is never the same filenumber used twice for a client.

由于所有两个文档中的_id字段不能相同,所以所有ouchdb文档都是唯一的.查看查看食谱

All couchdb documents are unique since the _id fields in two documents can't be the same. Check out the view cookbook

这很简单:在CouchDB数据库中,每个文档必须具有唯一的_id字段.如果您在数据库中需要唯一值,只需将它们分配给文档的_id字段,CouchDB将为您强制唯一性.

This is an easy one: within a CouchDB database, each document must have a unique _id field. If you require unique values in a database, just assign them to a document’s _id field and CouchDB will enforce uniqueness for you.

但是有一个警告:在分布式情况下,当您运行一个以上的接受写入请求的CouchDB节点时,只能保证每个节点或CouchDB外部的唯一性. CouchDB将允许将两个相同的ID写入两个不同的节点.复制时,CouchDB将检测到冲突并相应地标记文档.

There’s one caveat, though: in the distributed case, when you are running more than one CouchDB node that accepts write requests, uniqueness can be guaranteed only per node or outside of CouchDB. CouchDB will allow two identical IDs to be written to two different nodes. On replication, CouchDB will detect a conflict and flag the document accordingly.

根据评论进行编辑

如果要根据另一文档的成功插入来增加一个文档中的字段

In a case where you want to increment a field in one document based on the successful insert of another document

在这种情况下,您可以使用单独的文档.您插入一个文档,等待成功响应.然后添加另一个文档,例如

You could use separate documents in this case. You insert a document, wait for the success response. Then add another document like

{_id:'some_id','count':1}

通过此操作,您可以设置地图简化视图,该视图仅对这些文档的结果进行计数,并且具有更新计数器.您要做的就是插入一个新文档以反映插入成功,而不是更新单个文档进行更新.

With this you can set up a map reduce view that simply counts the results of these documents and you have an update counter. All you are doing is instead of updating a single document for updates you are inserting a new document to reflect a successful insert.

我总是以这样一种情况结束:文件插入失败会导致DB处于不一致状态,尤其是在另一个客户端同时成功插入文件的情况下.

I always end up with the case where a failed file insert would leave the DB in an inconsistent state especially with another client successfully inserting a file at the same time.

好的,我已经描述了如何在单独的文档上进行更新,但是即使在更新单个文档时,如果您可以避免出现不一致的情况,也可以:

Okay so I already described how you can do updates over separate documents but even when updating a single document you can avoid inconsistency if you :

  1. 插入新文件
  2. 当ouchdb提供成功消息时,->尝试更新计数器.

这为什么起作用?

之所以起作用,是因为尝试更新update document时必须提供_rev字符串.您可以将_rev视为文档的本地状态.考虑这种情况:-

This works because because when you try to update the update document you must supply a _rev string. You can think of _rev as a local state for your document. Consider this scenario:-

  1. 您阅读了将要更新的文档.
  2. 您更改了一些字段.
  3. 与此同时,另一个请求已经更改了原始文档.这意味着文档现在有了一个新的_rev
  4. 但是,您请求长沙发数据库使用在步骤#1中读取的stale _rev更新文档.
  5. Couchdb将生成一个异常.
  6. 您再次阅读该文档可获得最新的_rev并尝试对其进行更新.
  1. You read the document that is to be updated.
  2. You change some fields.
  3. Meanwhile another request has already changed the original document. This means the document now has a new _rev
  4. But You request couchdb to update the document with a _rev that is stale that you read in step #1.
  5. Couchdb will generate an exception.
  6. You read the document again get the latest _rev and attempt to update it.

因此,如果执行此操作,则始终将文档更新为最新版本.我希望这可以使事情变得更清楚.

So if you do this you will always have to update against the latest revision of the document. I hope this makes things a bit clearer.

注意:

如丹尼尔(Daniel)指出的,_rev规则不适用于批量更新.

As pointed out by Daniel the _rev rules don't apply to bulk updates.

这篇关于CouchDB/Couchbase/MongoDB事务仿真?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆