@vetsmen

Асинхронная функция выполняется несколько раз в sql запросом?

Доброго времени суток. Имею функцию, которая проверят игрока, выполнил и он квест, заносит этот квест в активированные и выдает баланс:
var setStatistic = function(type, userid) {
	connection.query('SELECT * FROM Quests WHERE Quests.quests <> \'0\' AND Quests.id NOT IN (SELECT questid FROM QuestsActive WHERE QuestsActive.userid = ?) LIMIT 1', [userid]).then(function(questdata) {
		if(questdata && questdata[0]) {
			connection.query('SELECT COUNT(id) AS quests FROM QuestsActive WHERE userid = ?', [userid]).then(function(result){
				var questcount = parseInt(questdata[0].quests, 10),
					usercount = parseInt(result[0].quests, 10);
				if(usercount >= questcount) {
					connection.query('INSERT INTO QuestsActive SET ?', {'questid': questdata[0].id, 'userid': userid}).then(function(result){
						updateBalance(questdata[0].prize, userid).then(function(result){
					    	console.log('ok ' + userid + ' type: ' + type);
				    	}).catch(function(error){
							console.log(error);
						});
					}).catch(function(error){
						console.log(error);
					});
				}
			}).catch(function(error){
				console.log(error);
			});
		}
	}).catch(function(error){
		console.log(error);
	});

};

Однако столкнулся с такой проблемой, что если ее вызвать 3 раза подряд на сервере, то проверка на наличие активированного квеста не срабатывает и баланс выдается 3 раза. Как быть в такой ситуации?
  • Вопрос задан
  • 252 просмотра
Решения вопроса 1
@BorisKorobkov Куратор тега MySQL
Web developer
1. Называйте переменные осмысленно. Когда куча запросов, то сложно понять, что же за result

2. Не пишите callback hell. Например, используйте promise.

3. Когда несколько одновременных http-запросов, то к моменту третьего SQL результаты двух первых уже могут быть неактуальны.
Почитайте про уровни изолированности.
Рекомендую использовать advisory locks в PostgreSQL. Или другие локи.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы