Reputation: 130
I have a Node application which runs in cluster mode with pm2.
I also have a function which checks if a specific row is in a db table. If the row is missing it creates the row otherwise a value is set and saved.
I only need one row for each combination of userId and groupId.
function someFunction()={
return Activation.findOne({ where: { userId: userId, groupId: groupId } })
.then(activationObject => {
if (!activationObject) {
return Activation.create({ userId: userId, groupId: groupId, activationTime: sequelize.fn('NOW') })
} else {
activationObject.activationTime = sequelize.fn('NOW');
return activationObject.save()
}
})
}
How can I avoid race conditions when running node in cluster mode? Currently if first worker checks the row is available and the second checks at the same time both get no result and in the end we have two newly created rows instead of one.
I know that Sequelize provides a findOrCreate()
method but I wanted an easy understandable example.
Upvotes: 0
Views: 690
Reputation: 2468
I'm late to the party, but if you have more complicated things to check in your first query, using a transaction with the appropriate isolation level can be helpful
This answer gives a nice example: TypeORM Database Lock: Please explain how to use database lock in TypeORM using setLock() function
Upvotes: 0
Reputation: 346
The easiest way would be to add a UNIQUE
constraint for the combination of userId
and groupId
with an ON CONFLICT REPLACE
clause, and always create a new row instead of updating. This will cause a newly inserted row with the new activationTime
to replace the old row.
You can additionally check the number of rows inserted to tell whether the insert succeeded or not.
Example: UNIQUE (userId, groupId) ON CONFLICT REPLACE
Upvotes: 2