いいえ。CouchDBは「楽観的並行性」モデルを使用しています。簡単に言うと、これは、更新と一緒にドキュメントバージョンを送信することを意味し、現在のドキュメントバージョンが送信したものと一致しない場合、CouchDBは変更を拒否します。
本当に、一見シンプルです。CouchDBの多くの通常のトランザクションベースのシナリオをリフレーミングできます。ただし、CouchDBを学習するときは、RDBMSドメインの知識を捨てる必要があります。CouchをSQLベースの世界に成形しようとするよりも、より高いレベルから問題に取り組むことが役立ちます。
在庫を追跡する
あなたが概説した問題は、主に在庫の問題です。アイテムを説明するドキュメントがあり、「利用可能な数量」のフィールドが含まれている場合は、次のような同時実行の問題を処理できます。
- ドキュメントを取得し、
_rev
CouchDBが送信するプロパティに注意してください
- ゼロより大きい場合は、数量フィールドをデクリメントします
_rev
プロパティを使用して、更新されたドキュメントを送り返します
_rev
現在保存されている番号と一致する場合は、完了してください。
- 競合がある場合(
_rev
一致しない場合)、最新のドキュメントバージョンを取得します
この場合、考えられる2つの障害シナリオがあります。最新のドキュメントバージョンの数量が0の場合、RDBMSの場合と同じように処理し、購入したいものを実際に購入できないことをユーザーに警告します。最新のドキュメントバージョンの数量が0より大きい場合は、更新されたデータで操作を繰り返し、最初からやり直すだけです。これにより、RDBMSよりも少し多くの作業を行う必要があり、頻繁に競合する更新がある場合は少し面倒になる可能性があります。
さて、私が今与えた答えは、RDBMSで行うのとほとんど同じ方法でCouchDBで物事を行うことを前提としています。私はこの問題に少し違ったアプローチをするかもしれません:
まず、すべての記述子データ(名前、写真、説明、価格など)を含む「マスター製品」ドキュメントから始めます。それから私はのためのフィールドで、各特定のインスタンスに対して、「棚卸チケット」ドキュメントを追加したい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 });
}
}
これにより、使用可能な「チケット」のリストがプロダクトキー別に表示されます。誰かがハンマーを購入したいときにこれらのグループを取得し、更新を送信して(とを使用し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