1. ホーム
  2. database

[解決済み] 私はCouchDBでトランザクションとロックを行うことができますか?

2023-07-15 21:17:42

質問

トランザクション(開始、コミット、ロールバック)、ロック(更新のための選択)を行う必要があります。 どのように私はドキュメントモデルのデータベースでそれを行うことができますか?

編集してください。

ケースはこうです。

  • オークションサイトを運営したい。
  • また、直接購入の方法も考えています。
  • 直接購入では、私は数量がゼロより大きい場合にのみ、アイテムレコードの数量フィールドをデクリメントする必要があります。それが、私がロックとトランザクションを必要とする理由です。
  • ロックおよび/またはトランザクションなしでそれに対処する方法がわかりません。

私はCouchDBでこれを解決することができますか?

どのように解決するには?

いいえ、CouchDBは"楽観的な並行処理"を使用しています;モデル。 最も単純な用語では、これはちょうどあなたがあなたの更新と一緒に文書のバージョンを送信することを意味し、現在のドキュメントのバージョンは、あなたが送ったものと一致しない場合、CouchDBは、変更を拒否します。

それは本当に、欺瞞的に簡単です。 あなたは、CouchDBのための多くの通常のトランザクションベースのシナリオをリフレーミングすることができます。あなたはしかし、CouchDBを学ぶとき、あなたのRDBMSのドメイン知識を捨てる並べ替えをする必要があります。 それは、より高いレベルから問題にアプローチするのではなく、SQLベースの世界にCouchを成形しようとすると便利です。

<強い 在庫を追跡する

あなたが概説した問題は、主に在庫の問題です。 アイテムを説明するドキュメントがあり、そこに "利用可能な数量" のフィールドが含まれていれば、このように並行処理の問題を処理することができます。

  1. ドキュメントを取得し、そのドキュメントに含まれる _rev CouchDBは一緒に送信することをプロパティ
  2. プロパティを使用します。
  3. もし _rev が現在保存されている番号と一致したら、完了です!
  4. 衝突があった場合 ( _rev がマッチしない場合)、最新バージョンのドキュメントを取得する。

この例では、考えるべき2つの可能な失敗のシナリオがあります。 最新のドキュメントバージョンの数量が 0 の場合、RDBMS と同様にそれを処理し、購入したかったものが実際には購入できないことをユーザーに警告します。 もし、最新のドキュメントのバージョンが0より大きい数量を持つ場合、単に更新されたデータで操作を繰り返し、最初からやり直します。 これは、RDBMS が行うよりも少し多くの作業を行うことを余儀なくされ、頻繁に矛盾する更新がある場合は少し迷惑になる可能性があります。

さて、私がちょうど与えた答えは、あなたがRDBMSでやるのと同じようにCouchDBで物事を行うつもりであることを前提としています。 私は少し異なって、この問題にアプローチするかもしれません。

私は&quot;マスター製品で始まるだろう;すべての記述子データ(名前、画像、説明、価格など)が含まれているドキュメント。 次に、特定のインスタンスごとに、以下のフィールドを持つ「在庫チケット」ドキュメントを追加します。 _revproduct_key . もしあなたがハンマーのモデルを販売していて、販売するものが20個ある場合、次のようなキーを持つ文書があるかもしれません。 claimed_by , hammer-1 などで、利用可能な各ハンマーを表します。

次に、利用可能なハンマーのリストを表示するビューを作成し、合計を表示するための縮小機能を追加します。 これらは完全に思いつきですが、作業用のビューがどのように見えるかのアイデアを与えてくれるはずです。

地図

hammer-2

これは、プロダクト キーによって、利用可能なチケットのリストを提供します。 誰かがハンマーを買おうとしたときに、これらのグループを取得し、更新を送信して反復することができます ( function(doc) { if (doc.type == 'inventory_ticket' && doc.claimed_by == null ) { emit(doc.product_key, { 'inventory_ticket' :doc.id, '_rev' : doc._rev }); } } id を使用します)。(以前にクレームしたチケットは更新エラーになります)。

削減する

_rev

この reduce 関数は、単に未請求の function (keys, values, combine) { return values.length; } のアイテムの総数を返すだけなので、購入可能なハンマーの数を知ることができます。

注意事項

この解決策は、あなたが提示した特定の問題に対して、およそ3.5分の総発想時間を表しています。 これを行うより良い方法があるかもしれません! とはいえ、競合する更新を大幅に削減し、競合に新しい更新で対応する必要性を削減することができます。 このモデルでは、複数のユーザーが一次製品入力のデータを変更しようとすることはないでしょう。 最悪の場合、複数のユーザーが 1 つのチケットを請求しようとすることがあり、そのうちのいくつかをビューから取得した場合は、単に次のチケットに移動して再試行するだけです。

参照 https://wiki.apache.org/couchdb/Frequently_asked_questions#How_do_I_use_transactions_with_CouchDB.3F