Мой вопрос в том, что я пытаюсь разработать службу REST NodeJs, с помощью которой люди могут зарегистрироваться на моем сайте. Мой поток регистрации выглядит примерно так:
1.Проверьте, если какой-либо пользователь выходит с тем же адресом электронной почты
Если пользователь существует, отправьте ответ, чтобы сообщить, что пользователь уже существует
Если пользователь не существует, создайте объект пользователя с введенными данными.
4. Теперь вставьте это в БД.
Теперь позвольте сказать, что у меня есть два пользователя "A" и "B", они ввели те же идентификаторы электронной почты. Теперь пусть пользователь A и B оба достигнут точки, где мой код проверяет, выходит ли пользователь или нет, они оба получат этот пользователь не существует, и их поток будет двигаться в направлении создания объекта и создания объекта в БД. Теперь в этом случае, если в Java есть синхронизированный блок, мы можем запретить эти два случая создавать объект одновременно, но в NodeJS, как я могу это сделать? и как избежать этой гонки вокруг ситуации?
Может ли NodeJ быть однопоточным и иметь общий стек, предотвратит это? или если есть какой-либо другой способ сделать это в NodeJs? Я очень новичок в NodeJs, извините, если я упомянул что-то не так.
Так строго говоря, node.js работает на одном потоке, но ваш рабочий процесс программы, включающий ввод-вывод (база данных, файловая система), клиент и все, работает на многих потоках.
Источник: может ли код node.js привести к условиям гонки?
Вы можете предотвратить эту ситуацию на уровне базы данных с помощью транзакций. Или вы можете предотвратить и на прикладном уровне.
Вы можете использовать (и использовать) транзакции (предположим SQL), чтобы обеспечить целостность и целостность данных.
Кроме того, отслеживать статус регистра в памяти с помощью hashmap для введенных писем:
var PENDING_EMAILS = {}
app.post("/register", function(req, res) {
var email = req.body.email
if(PENDING_EMAILS[email]) {
return res.send("Email is busy")
}
PENDING_EMAILS[email] = true // check this email as busy
// register operation
// check in DB etc...
delete PENDING_EMAILS[email] // also, release hashmap key when register finishes or when there is an error
})
Этот подход предотвращает вашу проблему.
email
объявлена как уникальный индекс, то при попытке создать запись B получит ошибку. Обработка этой ошибки и все в порядке. (Таким образом, вам даже не нужно проверять, существует ли пользователь - просто попробуйте сделать это и откажитесь, если база данных выдаст ошибку целостности.)