1

私の問題の説明は次のとおりです。

  1. ロード バランサーの背後に、nodejs (express.js) で記述された x 個の Web ワーカーがあります。これらのワーカーはデータを mongodb (mongoose.js) に書き込みます。
  2. ハンドラーのミドルウェア チェーンのある時点で、次のロジックを実行するようにエンドポイント y をセットアップしました。要求しているユーザーがデータベースに存在する場合は、それをフェッチし、いくつかのフィールドを更新してから保存します。存在しない場合は、mongo に挿入します。

ノート!ドメイン固有のロジック、つまり. ユーザーがすでに存在する場合は特定の値で更新し、そうでない場合は別の値で挿入します。

  1. 問題は、多くの場合、同じユーザー (データベースにまだ存在していないユーザー) からの 2 つのリクエストが 2 つの異なるワーカーにヒットすることです。ユーザー処理ミドルウェアが起動すると、両方のワーカーがユーザーが存在しないと判断し、ユーザーを挿入してから更新しようとします。当然、これはエラーを引き起こします。検証エラー: ユーザー検証などごとに一意の電子メールを設定しました。

どうすればこれを防ぐことができますか?

4

1 に答える 1

2

これを実現するために、演算子を使用$setおよび$setOnInsert更新できます。

MongoDB $setOnInsert docsから:

upsert: true を使用した更新操作でドキュメントが挿入される場合、$setOnInsert は指定された値をドキュメントのフィールドに割り当てます。更新操作の結果が挿入されない場合、$setOnInsert は何もしません。

upsert: true を指定した db.collection.update() で一致するドキュメントが見つかった場合、MongoDB は更新を実行し、$set 操作を適用しますが、$setOnInsert 操作は無視します。

したがって、これでうまくいくはずです:

var now = Date.now();

Users.update({ _id: 1 }, {
  $set:         { updatedAt: now },
  $setOnInsert: { createdAt: now }
}, {upsert: true}, function(err, doc) {

  // resultant doc is available here

})
于 2015-01-29T23:24:50.707 に答える