error repeated many times when using findByIdAndUpdate

Previously this command worked very correctly, but in the last few days it has had an error of running over and over again 2-3 times, making the meaning of the balance update command incorrect.

await USER.findByIdAndUpdate(
{ _id: getBetUser[index].user._id },
{
money: Number(moneyuser.money) + Number(money_result),
totalwin: Number(moneyuser.totalwin) + Number(money_result),
}
);

full code:

cron.schedule(“0 */5 * * * *”, async () => {
try {
const Setting = await setting.find();
const getBetUser = await historyxucsac5p.find({ status_bet: “Pending” });
if (getBetUser.length != 0 && Setting.length > 0) {
for (let index = 0; index < getBetUser.length; index++) {

            const date = new Date() - new Date(getBetUser[index].id_bet.createdAt);
            if (date > 59000 * 5) {
                let choose_user = getBetUser[index].state.split(" ");
                let money_result = 0;
                choose_user.map((item) => {
                    if (FuncActions.ResultXucSac(getBetUser[index].id_bet.result).includes(Number(item))) {
                        if (Number(item) < 9) {
                            money_result +=
                                (Number(getBetUser[index].money) / choose_user.length) *
                                Number(Setting[0].xucsac5p);
                        } else if (Number(item) > 9 && Number(item) < 99) {
                            money_result +=
                                (Number(getBetUser[index].money) / choose_user.length) *
                                Number(Setting[0].haitrung5);
                        } else if (Number(item) >= 111) {
                            money_result +=
                                (Number(getBetUser[index].money) / choose_user.length) *
                                Number(Setting[0].batrung5);
                        }
                    }
                });
                if (money_result > 0) {
                    await historyxucsac5p.findByIdAndUpdate(
                        { _id: getBetUser[index]._id },
                        { status_bet: "Win", moneythang: Number(money_result) }
                    );
                    const moneyuser = await USER.findById({
                        _id: getBetUser[index].user._id,
                    });
                    await USER.findByIdAndUpdate(
                        { _id: getBetUser[index].user._id },
                        {
                            money: Number(moneyuser.money) + Number(money_result),
                            totalwin: Number(moneyuser.totalwin) + Number(money_result),
                        }
                    );
                } else {
                    await historyxucsac5p.findByIdAndUpdate({ _id: getBetUser[index]._id }, { status_bet: "Lose" });
                }
            }
        }
    }
} catch (error) {
    console.log(err);
}

});

You don’t say what the error is but your code just updates the database based on currently held values in memory so if you had multiple clients that could cause chaos.
If it is single threaded or this is the ONLY place that updates those collections / fields then you may not need to worry about this.
Can you put pseudocode up on what it’s expected to do, along with example data that has caused the issue.

If dealing with money updates then it can be crucial to ensure that when you send an update to the database that you are updating data based on the latest information.
Either get the server to calculate the update or send the last known value as an extra match condition or have some form of checksum or timestamp for a document so you know that you’re updating data that’s in the same state on the server as you have in the database.
You can then check the update result to determine if the update completed and deal with it appropriately, in fact you should be doing that anyway ideally if ensuring that updates complete as expected is important to you. You need to avoid lost-updates if they are even a remote possibility.

You could also think about using transactions if it’s critical that multiple updates all either complete or do no complete.

You have no logging in the above, to try and diagnose the issue why not add logging to a collection to store how often each part is run and what the results are within loops and return results or at least their size.

1 Like