За последние 24 часа нас посетили 22866 программистов и 1225 роботов. Сейчас ищут 757 программистов ...

Проблема с отправкой двойных запросов к Базе Данных при заходе на страницу

Тема в разделе "PHP для новичков", создана пользователем crystaltrumpet, 8 май 2019.

Метки:
  1. crystaltrumpet

    crystaltrumpet Новичок

    С нами с:
    8 сен 2018
    Сообщения:
    23
    Симпатии:
    0
    Добрый день сталкиваемся в последние месяцы с проблемой отправки двойных запросов на изменение в базе данных из за этого возникают ошибки = двойные выполнения одного и того же действия
    К примеру:
    При заходе на определенную страницу скриптом идет запрос в базу данных на сравнение с текущим временем
    Если настоящее время больше чем то что в определенной строке в базе данных происходит некое действие с базой данных
    Если одновременно в ту же секунду на одну и ту же страницу заходят два разных пользователя и к примеру один зашел на полсекунды раньше, то идет запрос в БД и из за задержки нашего сервера зарез полсекунды заходит другой участник и скрипт не получив ответ от предидущего и не сделав изменения отправляет точно такой же запрос и в итоге они обрабатываются сервером и получается двойные изменения.
    POST GET - на этой странице нет. Зашел - идет запрос в бд при определенных условиях идут изменения в бд.
    подключен cloudflare
     
  2. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    @crystaltrumpet Добавьте в вашу таблицу еще один столбик который по умолчанию null . И перед тем как произвести какие то там изменения проверяйте его на is_null(). Если true то производите свои изменения и запиши в этот столбик единицу. Второй пользователь перед изменениями тоже проверит этот столбик и если is_null false то уже ничего делать не будет.
     
  3. crystaltrumpet

    crystaltrumpet Новичок

    С нами с:
    8 сен 2018
    Сообщения:
    23
    Симпатии:
    0
    Спасибо за ответ но я не представляю как это сделать в плане Вот я зашел Null =true я делаю изменения и тут же ставлю 1, но а что потом? изменения произвел нужно же обратно перевести в NULL так как эта строка еще может много раз меняться за день, так как это отнимаются деньги со счета.... А если я переведу обратно то дублированный запрос тоже пройдет и деньги отнимутся второй раз также
     
  4. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    Тогда все еще проще, раз время вы сравнивать умеете, пишите туда вместо единицы время изменения. И условие если время последнего изменения допустим меньше одной минуты то данные не менять.
     
  5. crystaltrumpet

    crystaltrumpet Новичок

    С нами с:
    8 сен 2018
    Сообщения:
    23
    Симпатии:
    0
    Чтобы Вы понимали код! Там идет перебор цикла и бывает что изменяется несколько раз цифра за все циклы
     
  6. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    видел я уж ваш код, капец =) во первых while можно все тоже написать что и в foreach у вас, во вторых так не делается. Но раз уж вы делаете то можно просто условие написать в цикле. if(дата больше одной минуты) делаем update если нет то не делаем.
     
  7. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.825
    Симпатии:
    738
    Адрес:
    Татарстан
    А чего гадать то, покажите код... Хотя я честно говоря смысла во всём что написали пока не уловил.. все абстрактно конкретно на пальцах объясните что и зачем вы конкретно меняете в бд...

    Самый простой пример - типа у нас счётчик просмотра страниц, показали страницу - увеличили счётчик в бд
     
  8. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    @ADSoft я что то такое делал по неопытности, update конкретной строки если нужны изменения. В будущем до него дойдет что лучше делать inser и потом доставать одну строчку с последним изменением =)
    а код он показывал, но потом убрал почему то.
     
  9. crystaltrumpet

    crystaltrumpet Новичок

    С нами с:
    8 сен 2018
    Сообщения:
    23
    Симпатии:
    0
    Случайно убрал))

    Поэтому и написал в разделе новичков, так как возможно некий умный, опытный человек покажет мне как это можно оптимизировать
     
  10. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    ну во первых можно упростить до:
    PHP:
    1. public function CheckTime()
    2.     {
    3.         $db = $this->db;
    4.         $now = time();
    5.         $now_time = time() - 60;
    6.         $sql = "select * from `db_product_time` where `status`=1 and `date_del`<=$now";
    7.         $db->Query($sql);
    8.         $arr = array();
    9.         if ($db->NumRows()>0)
    10.         {
    11.             while($row = $db->FetchArray())
    12.             {
    13.                if($now_time < $row['date_del']){
    14.  
    15.                      $id = $row['id'];
    16.                      $par = $row['name'];
    17.                      $user = $row['id_user'];
    18.                      $sql = "update `db_users_b` set `$par`=`$par`-1 where `id`=$user ;
    19.                              update `db_product_time` set  `status`=0, `date_del`=$now where `id`=$id";
    20.                      $db->Query($sql);
    21.                 }
    22.             }
    23.         }
    24.     }
    а поидее и это не правильно наверное, но попробуйте.