いいえ。CouchDB は「楽観的並行性」モデルを使用します。簡単に言うと、これは、更新と共にドキュメント バージョンを送信し、現在のドキュメント バージョンが送信したものと一致しない場合、CouchDB が変更を拒否することを意味します。
実にシンプルです。CouchDB の多くの通常のトランザクション ベースのシナリオを再構築できます。ただし、CouchDB を学習するときは、RDBMS ドメインの知識を捨てる必要があります。Couch を SQL ベースの世界に合わせようとするのではなく、より高いレベルから問題にアプローチすることが役に立ちます。
在庫の追跡
あなたが概説した問題は、主に在庫の問題です。アイテムを説明するドキュメントがあり、「利用可能な数量」のフィールドが含まれている場合、次のような同時実行の問題を処理できます。
- ドキュメントを取得し、
_rev
CouchDB が送信するプロパティをメモします。
- ゼロより大きい場合、数量フィールドを減らします
_rev
プロパティを使用して、更新されたドキュメントを送り返します
_rev
が現在保存されている番号と一致する場合は完了です。
- 競合がある場合 (
_rev
一致しない場合)、最新のドキュメント バージョンを取得する
この場合、考えられる 2 つの障害シナリオがあります。最新のドキュメント バージョンの数量が 0 の場合、RDBMS の場合と同じように処理し、購入したいものを実際に購入できないことをユーザーに警告します。最新のドキュメント バージョンの数量が 0 より大きい場合は、更新されたデータで操作を繰り返し、最初からやり直すだけです。これにより、RDBMS よりも少し多くの作業を行う必要があり、競合する更新が頻繁に行われる場合は少し面倒になる可能性があります。
さて、先ほどの回答は、CouchDB で RDBMS で行うのとほぼ同じ方法で作業を行うことを前提としています。私はこの問題に少し違ったアプローチをするかもしれません:
すべての記述子データ (名前、写真、説明、価格など) を含む「マスター製品」ドキュメントから始めます。次に、特定のインスタンスごとに と のフィールドを持つ「在庫チケット」ドキュメントを追加しproduct_key
ますclaimed_by
。ハンマーのモデルを販売していて、販売するモデルが 20 個ある場合、利用可能な各ハンマーを表す 、 などのhammer-1
キーを含むドキュメントがあるかもしれません。hammer-2
次に、使用可能なハンマーのリストを表示するビューを作成し、reduce 関数を使用して「合計」を表示します。これらは完全に思いつきではありませんが、作業ビューがどのように見えるかについてのアイデアを提供するはずです。
地図
function(doc)
{
if (doc.type == 'inventory_ticket' && doc.claimed_by == null ) {
emit(doc.product_key, { 'inventory_ticket' :doc.id, '_rev' : doc._rev });
}
}
これにより、利用可能な「チケット」の一覧がプロダクト キー別に表示されます。誰かがハンマーを購入したいときにこれらのグループを取得し、取得に成功するまで ( and を使用しid
て_rev
) 更新を送信することを繰り返すことができます (以前に取得したチケットは更新エラーになります)。
減らす
function (keys, values, combine) {
return values.length;
}
この reduce 関数は、請求されていないアイテムの総数を返すだけなinventory_ticket
ので、購入可能な「ハンマー」の数を知ることができます。
注意事項
この解決策は、提示された特定の問題について、合計約 3.5 分の思考に相当します。これを行うより良い方法があるかもしれません!とはいえ、競合する更新が大幅に減少し、新しい更新で競合に対応する必要性が削減されます。このモデルでは、複数のユーザーがプライマリ製品エントリのデータを変更しようとすることはありません。最悪の場合、複数のユーザーが 1 つのチケットを要求しようとすることになり、ビューからそれらのいくつかを取得した場合は、次のチケットに移動して再試行するだけです。
参照: https://wiki.apache.org/couchdb/Frequently_asked_questions#How_do_I_use_transactions_with_CouchDB.3F