@Baklajan888

Как решить проблему с очередью запросов MySQL?

Возникла такая проблема, что при одновременных запросах не создается никакой очереди.
Если пользователь нажмет кнопку 1 раз и дождется ответа, то на сервер отправится 1 AJAX-запрос и все сработает как нужно.
Но если человек нажмет ее несколько раз, причем очень быстро, то что-то идет не так:
Запрос не дожидается обновления данных в БД и выполняет их еще раз. Тем самым баланс пользователя уходит в минус, а заявка на вывод создается 2+ раз.

Перепробовал различные способы:
Транзакции, lockForUpdate, sharedLock.
SET TRANSACTION ISOLATION LEVEL READ COMMITTED,

Ничего не помогло. Есть ли варианты, каким образом это можно исправить?

public function withdraw(Request $r) {
        $price = $r->summa;

        if($this->user->golds < $price) return ['type' => 'error', 'text' => 'Недостаточно голды на балансе'];
		
        $countUserWithdraw = Withdraw::where('user_id', $this->user->id)->where('status', '0')->count();
        if($countUserWithdraw >= 1) return ['type' => 'error', 'text' => 'Одновременно выставленных выводов в статусе ожидание может быть только 1, попробуйте позже'];
		
		$this->user->golds -= $price;
		$this->user->save();

		$withID = Withdraw::create([
        	'user_id' => $this->user->id,
            'market_price' => $r->summa*1.25,
            'price' => $r->summa,
            'screen' => $this->user->uploadImage,
            'time' => Carbon::now()->format('Y.m.d'),
            'status' => 0
        ])->id;

		$data = [
			'id' => $withID,
			'market_price' => $price*1.25,
			'price' => $price,
			'time' => Carbon::now()->format('Y.m.d') 
		];

        return ['type' => 'success', 'text' => 'Вы успешно оставили заявку на вывод', 'golds' => round($this->user->golds, 2), 'info' => $data];
	}


Наглядный пример:

1. Отправил 2 запроса с задержкой +- 0.2 сек
0l71HFR.png
2. Отправил несколько запросов без задержки. Произошло то, о чем говорил в самом начале
Jzw8RLY.png
  • Вопрос задан
  • 198 просмотров
Пригласить эксперта
Ответы на вопрос 1
vfreelancer
@vfreelancer
php
Обернуть все запросы в DB::transaction(); а на фронте пользователю при клике блокировать кнопку, пока ответ не придет.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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