I am facing an issue with concurrent requests resulting in duplicate entries. Our system checks whether a user exists and creates a new one if not, using middleware. However, when multiple concurrent requests for a new user occur, each request creates the same user, leading to duplication. Below is the repository code for this functionality.
async somefunction(usrId: number) {
const t = await sequelize.transaction();
try {
const user = await usermodel.findOne({
where: {
userId: usrId,
},
transaction: t,
});
if (!user) {
const puraUser = await mainusermodel.findOne({
where: {
id: usrId,
},
transaction: t,
});
const dob = puraUser.dob;
const age = dob
? UserRepository.calculateAge(new Date(dob))
: 0;
try {
const dbUser = await usermodel.create(
{
userId: usrId,
age,
streakDays: 0,
},
{
transaction: t,
}
);
await tblUserSettingsModel.create(
{
userId: dbUser.id,
lowerLimit: defaultUserSettings.lowerLimit,
upperLimit: defaultUserSettings.upperLimit,
unitId: defaultUserSettings.unitId,
},
{
transaction: t,
}
);
await t.commit();
return dbUser;
} catch (error) {
if (error.name === 'SequelizeUniqueConstraintError') {
const dbUser = await tblUserDetailModel.findOne({
where: { userId: usrId },
transaction: t,
});
await t.commit();
return dbUser;
} else {
return null;
}
}
} else {
await t.commit();
return user;
}
} catch (err) {
await t.rollback();
logger.error(`CREATE_USER for userId ${usrId}`, err);
return null;
}
}
I have tried using isolation levels up to REPEATABLE READ, but the issue persists. When using the SERIALIZABLE isolation level, I encounter deadlock errors.