Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 95116 invoked from network); 23 Mar 2009 16:53:27 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 23 Mar 2009 16:53:27 -0000 Received: (qmail 65781 invoked by uid 500); 23 Mar 2009 16:53:27 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 65701 invoked by uid 500); 23 Mar 2009 16:53:27 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 65692 invoked by uid 500); 23 Mar 2009 16:53:27 -0000 Delivered-To: apmail-incubator-couchdb-commits@incubator.apache.org Received: (qmail 65689 invoked by uid 99); 23 Mar 2009 16:53:27 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Mar 2009 16:53:27 +0000 X-ASF-Spam-Status: No, hits=-1999.8 required=10.0 tests=ALL_TRUSTED,WHOIS_MYPRIVREG X-Spam-Check-By: apache.org Received: from [192.87.106.226] (HELO aurora.apache.org) (192.87.106.226) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Mar 2009 16:53:20 +0000 Received: from aurora.apache.org (localhost [127.0.0.1]) by aurora.apache.org (8.13.8+Sun/8.13.8) with ESMTP id n2NGqwi1008043 for ; Mon, 23 Mar 2009 16:52:58 GMT Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Apache Wiki To: couchdb-commits@incubator.apache.org Date: Mon, 23 Mar 2009 16:52:58 -0000 Message-ID: <20090323165258.7806.30229@aurora.apache.org> Subject: [Couchdb Wiki] Update of "HTTP Document API" by DavidVanCouvering X-Virus-Checked: Checked by ClamAV on apache.org Dear Wiki user, You have subscribed to a wiki page or wiki category on "Couchdb Wiki" for change notification. The following page has been changed by DavidVanCouvering: http://wiki.apache.org/couchdb/HTTP_Document_API ------------------------------------------------------------------------------ === Modify Multiple Documents With a Single Request === - CouchDB provides a bulk insert/update feature. To use this, you make a ''POST'' request to the URI ''/{dbname}/_bulk_docs'', with the request body being a JSON document containing a list of new documents to be inserted or updated. The bulk post was (0.8.0) a transactional operation - all updates/insertions succeed, or all fail - but that behaviour has now changed as of 0.9.x, and each document may individually succeed or fail (see http://n2.nabble.com/couchdb-transactions-changes-td2289541.html for more information). + CouchDB provides a bulk insert/update feature. To use this, you make a ''POST'' request to the URI ''/{dbname}/_bulk_docs'', with the request body being a JSON document containing a list of new documents to be inserted or updated. Doc formats below are as per CouchDB 0.9.x. @@ -352, +352 @@ [ {"id": "0", "rev": "3682408536"}, {"id": "1", "rev": "3206753266"}, - {"id": "2", "error": "conflict", "reason": "Document update conflict."} + {"id": "2", "rev": "426742535"} ] }}} @@ -378, +378 @@ * If your database is partitioned (aka "sharded"), different documents within the transaction could live on different nodes in the cluster, and these kinds of transactional semantics don't work unless you use heavy, non-scalable approaches like two-phase commit. - With release 0.9 of CouchDB, transactional semantics have been changed to make sure CouchDB works consistently in single-node, replicated and partitioned environments. There are now two transactional models supported: + With release 0.9 of CouchDB, transactional semantics have been changed so that a CouchDB server behaves consistently in a single-node, replicated, and/or partitioned environment. There are now two transactional models supported: * '''non-atomic''' - This is the default behavior. Some documents may successfully be saved and some may not. It is up to the application to check that all documents were successfully saved/updated. - * '''all-or-nothing''' - To use this mode, pass "all-or-nothing" set to true in the request (e.g. ''/{dbname}/_bulk_docs?all-or-nothing=true)''. In this case either all the documents will commit successfully or none will. However, it does not do conflict checking, so the documents will be committed even if there are conflicts. If any documents have a conflict, then in the response that document will show a conflict error, for example + * '''all-or-nothing''' - To use this mode, pass {{{all-or-nothing=true}}} as a parameter to the request (e.g. ''/{dbname}/_bulk_docs?all-or-nothing=true)''. In this case either all the documents will commit successfully or none will. However, it does not do conflict checking, so the documents will be committed even if there are conflicts. If any documents have a conflict, then in the response that document will show a conflict error, for example, given the request {{{ { "docs": [ - {"_id": "0", "error:" "conflict"}, + {"_id": "0", "_rev": "3682408536", "integer": 10, "string": "10"}, {"_id": "1", "_rev": "3206753266", "integer": 2, "string": "2"}, {"_id": "2", "_rev": "426742535", "integer": 3, "string": "3"} ] } }}} - + You could potentially get the response - ---- /!\ '''Edit conflict - other version:''' ---- - == Transactional Semantics with Bulk Updates == + {{{ + { + "docs": [ + {"_id": "0", "error:" "conflict", "reason": "Document update conflict."}, + {"_id": "1", "_rev": "725846561", "integer": 2, "string": "2"}, + {"_id": "2", "_rev": "517381856", "integer": 3, "string": "3"} + ] + } + }}} - In previous releases of CouchDB, bulk updates were transactional - in particular, all requests in a bulk update failed if any request failed or was in conflict. There were a couple of problems with this approach: + In this case, documents with id 1 and 2 were successfully modified, while the document with id 0 had a conflict, with both versions being saved in the database. The application will then need to handle any conflict resolution. - - This doesn't actually work with replication. Replication doesn't provide the same transactional semantics, so downstream replicas won't see "all-or-nothing" transactional semantics. Instead, they will see documents in an inconsistent state until replication of all documents involved in the bulk update completes. With bidirectional replication it can get even worse, because you can get edit conflicts that must be fixed manually. + Note that this change makes explicit the fact that CouchDB is not a relational store does not guarantee relational semantics between documents. This is something you should be aware of when designing an application against CouchDB. - - If your database is partioned (aka "sharded"), different documents within the transaction could live on different nodes in the cluster, and these kinds of transactional semantics don't work unless you use heavy, non-scalable approaches like two-phase commit. + First of all, in a replicated environment, document changes are replicated independently, and in no defined order. So replicas can easily have documents that are temporarily inconsistent with each other. Secondly, even when running on a single node with no replication, it is possible for an update to one document to succeed while another has a conflict. For example, you may wish to delete a master document and cascade that delete to all of its related detail documents, but one of the details may have a conflicting update, so the delete will not succeed, and now you have a detail document with no owning master. - With release 0.9 of CouchDB, transactional semantics have been changed to make sure CouchDB works consistently in single-node, replicated and partitioned environments. There are now two transactional models supported: + In a replicated environment, the delete may even succeed locally, but subsequently when replicating with another replica, an update to a detail document may be detected, and now the delete is in conflict, and you can potentially have a detail document with no owning master document. - * *non-atomic* (default) - some documents may successfully be saved and some may not. It is up to the application to check that all documents were successfully saved/updated. + As a developer you need to be aware of these semantics and design your data model and your application with this in mind. - * *all-or-nothing* - either all the documents will commit successfully or none will. However, it does not do conflict checking, so the documents will be committed even if there are conflicts. Conflicting versions of the document will be saved. - - - non-atomic - In this mode, - - - ---- /!\ '''Edit conflict - your version:''' ---- - - ---- /!\ '''End of edit conflict''' ---- === DELETE === To delete a document, perform a ''DELETE'' operation at the document's location, passing the ''rev'' parameter with the document's current revision. If successful, it will return the revision id for the deletion stub.