Couchdbはデフォルトでトランザクションです。 couchdb内のすべてのドキュメントには、_rev
が含まれています 鍵。ドキュメントへのすべての更新は、この_rev
に対して実行されます キー:-
- ドキュメントを入手します。
- _revプロパティを使用して更新のために送信します。
- 更新が成功した場合は、ドキュメントの最新の_revを更新しています
- 更新が失敗した場合、ドキュメントは最新のものではありません。手順1〜3を繰り返します。
MrKurtによるこの回答> 詳細な説明については。
couchdbレシピ couchdbでトランザクションがどのように行われるかを示す銀行の例があります。
また、このアトミック銀行振込もあります couchdbでのトランザクションを説明する記事。
とにかく、これらすべてのリンクに共通するテーマは、_rev
に対して更新するcouchdbパターンに従う場合です。 データベースに一貫性のない状態を設定することはできません。
_id
以降、すべてのcouchdbドキュメントは一意です 2つのドキュメントのフィールドを同じにすることはできません。 クックブックを表示
を確認してください。
コメントに基づいて編集
この場合、別々のドキュメントを使用できます。ドキュメントを挿入し、成功の応答を待ちます。次に、
のような別のドキュメントを追加します
{_id:'some_id','count':1}
これにより、これらのドキュメントの結果をカウントするだけのマップリデュースビューを設定でき、更新カウンターがあります。あなたがしているのは、更新のために単一のドキュメントを更新する代わりに、成功した挿入を反映するために新しいドキュメントを挿入することです。
さて、私はすでに別々のドキュメントを更新する方法を説明しましたが、単一のドキュメントを更新する場合でも、次の場合は不整合を回避できます:
- 新しいファイルを挿入します
- couchdbが成功メッセージを表示したとき->カウンターの更新を試みます。
これが機能する理由
これが機能するのは、update document
を更新しようとすると、 _rev
を指定する必要があります ストリング。あなたは_rev
について考えることができます ドキュメントのローカル状態として。このシナリオを検討してください:-
- 更新されるドキュメントを読みました。
- いくつかのフィールドを変更します。
- 一方、別のリクエストで元のドキュメントが既に変更されています。これは、ドキュメントに新しい
_rev
が追加されたことを意味します - ただし、
_rev
でドキュメントを更新するようにcouchdbにリクエストします つまり、stale
手順1で読んだこと。 - Couchdbは例外を生成します。
- ドキュメントをもう一度読んで、最新の
_rev
を取得します 更新してみてください。
したがって、これを行う場合は、常にドキュメントの最新リビジョンに対して更新する必要があります。これにより、状況が少し明確になることを願っています。
注:
ダニエルが指摘したように、_rev
ルールは一括更新には適用されません。