2

NodeJS で RESTFul API を実装しようとしており、データベース バックエンドとして Mongoose (MongoDB) を使用しています。

次のコード例では、リクエストが同時に送信されたときに同じユーザー名で複数のユーザーを登録しますが、これは私が望んでいるものではありません。チェックを入れてみましたが!

NodeJS の非同期性が原因でこれが発生することはわかっていますが、これを適切に行う方法が見つかりませんでした。「findOne」メソッドがすぐに戻るように見え、registerUser が戻り、別のリクエストが処理されます。

ちなみに、別のAPI関数で既存のユーザーを確認したくはありません。登録段階で確認する必要があります。これを行う方法はありますか?

Controller.prototype.registerUser = function (req, res) {
    Users.findOne({'user_name': req.body.user_name}, function(err, user) {
        if(!user) {
            new User({user_name: req.body.user_name}).save(function(err) {
                if(!err) {
                    res.send("User saved");
                } else {
                    res.send("DB Error: Could not save user!");
                }
            });
        } else {
            res.send("User exists");
        }
    });
}
4

2 に答える 2

2

user_name をスキーマ内で一意に設定することを検討する必要があります。これにより、同一のユーザー名を設定するために同時に要求が行われた場合でも、user_name が一意のままになります。

于 2013-02-14T08:23:37.310 に答える
1

はい、これが起こっている理由は、複数のリクエストがコードを同時に実行できるため、 User.fineOne が false を複数回返す可能性があるためです。ちなみに、これは、リクエストごとに 1 つのスレッドを使用するスタックであっても、他のスタックでも発生する可能性があります。

これを解決するには、一度に 1 人のユーザーだけが処理されるように制御する方法が必要です。これは、すべての registerUser 要求をキューに追加し、それらを 1 つずつキューから取り出して res を呼び出すことで実現できます。キューから処理された後にのみ送信します。

または、ユーザー名のローカル配列を保持し、新しい要求が来るたびに、配列が既に存在するかどうかを確認することもできます。そうでない場合は、配列に追加して作業します。配列内にある場合は、「ユーザーが存在します」という応答を送信します。次に、ユーザーが正常に作成されたら、そのアレイから削除できます。(私はこれを 100% 考えているわけではありませんが、同様に機能すると思います。)

于 2013-02-13T22:59:11.267 に答える