2017-09-24 3 views
0

私は、API呼び出しで2つの別々のコレクションを更新する必要があるシナリオを持っています。 1つの更新が失敗した場合は、最初の更新を元に戻す必要があります。どちらの操作も正常に完了するかどうかを確認する方法を教えてください。明確にするために、ここに状況があります。 ExpressフレームワークでMongoJSを使用する。MongoDB複数のコレクションの更新

質問モデル

{ 
    _id: ObjectId(), 
    title: String, 
    description: String, 
    accepted: String, 
    // Some other fields 
} 

答えモデル

{ 
    _id: ObjectId(), 
    qid: String, //ObjectId of question its linked to 
    body: String, 
    accepted: boolean, 
    // Some other fields 
} 

アプローチ1: 最初の要求で送信されたidに対応する答えを引き出します。承認されたものとしてマークし、qidを入手してください。 qidに対応する質問文書にanswer idを挿入します。 2番目の操作が失敗した場合は、最初の操作を元に戻します。しかし、db接続が失われた場合、実行できません。

アプローチ2 最初にqidに対応する質問を取得します。 acceptedフィールドをanswer idに更新し、それに対応する回答を受け取り、それを承認済みとしてマークします。

そしてある答えが受け入れられた場合、我々は受け入れられないとして、他のすべての答えをする必要がある場合があります。それはの3番目のの操作です。さらに、それはトグル操作なので、すでに受け入れられていれば、その逆を行う必要があります。

私はこのような状況を処理するためのクリーンで安全な方法があります感じています。

答えて

0

MongoDBのdoes not have a way of doing multi-document transactions。したがって、このようなロールバックを行うためのきれいな方法はありません。アプリケーションに実装する必要があります。 MongoDBの文書では、two-phase commitパターンを使用してトランザクションのようなセマンティクスを作成することを提案しています。これを使用してロールバックを実装することはできますが、これはかなり面倒なことがあります。

代替は、あなたの文書スキーマを再考されます。 answer文書をquestion文書に埋め込むことはできますか?組み込み文書を使用すると、トランザクションを実装しようとするよりも、Mongoの機能をより有効に利用できます。 MongoDBは1つのドキュメントに対してアトミックな書き込みを行います。埋め込まれたドキュメントを更新する際にエラーが発生すると、全体の操作をロールバックできます。

+0

埋め込みに問題があります。それは答えのアレイであり、それはその後、一連の応答を持つでしょう。返信の更新を実行することは不可能になります。 – Nil

+0

ええと...回答と質問のように、回答と回答/質問を同時に更新したいですか?そうでない場合は、別のコレクションに返信し、応答の '_id'の配列を持つだけでうまくいくかもしれませんか? – tfogo

関連する問題