За последние 24 часа нас посетили 22409 программистов и 1139 роботов. Сейчас ищут 625 программистов ...

php, MySql, редкие дубли транзакций

Тема в разделе "PHP для профи", создана пользователем savsoft, 29 окт 2017.

Метки:
  1. savsoft

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

    С нами с:
    1 фев 2017
    Сообщения:
    96
    Симпатии:
    2
    Всем привет.

    Я новичок в php. Но вопрос задаю здесь, в теме для начинающих на него вряд ли ответят.

    Есть небольшое приложение на php, которое работает с базой MySql. Около 20 пользователей со смартфонов, планшетов, десктопов, до 10 транзакций на каждого пользователя в день, соответственно в месяц выходит всего до 5 тысяч транзакций.

    Пользователь находит клиента и открывает таблицу со всеми транзакциями выбранного клиента. Нажимает добавить и запускается скрипт, одностраничная форма для ввода данных. Пользователь вводит нужные поля, ставит чекбоксы и нажимает сохранить.

    По сабмиту открывается транзакция, пишутся данные, завершается транзакция, делается редирект
    на предыдущую страницу, после редиректа стоит exit().

    И все работает, но на 5 тысяч транзакций получается несколько дублей. Один пользователь точно
    запомнил, что он нажал сохранить и браузер или смартфон завис, а потом он увидел дважды введенную
    транзакцию. Как локализовать и с чем это связано - не знаю.

    Что делать?

    Могу сделать проверку на существование точь такой транзакции и не писать. Но хотелось бы понять
    откуда берутся дубли. Куда копать?

    Спасибо
     
  2. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.823
    Симпатии:
    736
    Адрес:
    Татарстан
    Для начала прочитать что такое транзакции. В Вашем случае это просто записи в бд, а не транзакции. Делать проверку на отправку данных клиентом не чаще чем например пары секунд. А так типа нажать можно умудрился несколько раз сабмит до того как форма исчезнет
     
  3. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Твитур, до кучи, проверяет содержимое поста. Возможно, считает хэш сообщений и сверяет его. Мессаги у них короткие, они могут это себе позволить. Если послать два одинаковых сообщения с малым интервалом, он пишет, мол "ой, кажется вы это уже писали".
     
  4. savsoft

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

    С нами с:
    1 фев 2017
    Сообщения:
    96
    Симпатии:
    2
    Нет, в моем случае именно транзакции. Типа

    Код (Text):
    1.    
    2. if(!empty($_POST["addrecord"])) {   // сабмит
    3.            
    4.         Здесь подготовка
    5.  
    6.         mysqli_begin_transaction($connection, MYSQLI_TRANS_START_READ_WRITE);
    7.        
    8.         Здесь INSERT, UPDATE
    9.            
    10.         if ($ErrorFlag == 0) {
    11.             mysqli_commit($connection);      
    12.    
    13.             $NewLocation = "mytable.php?id=" . $_SESSION["id"];
    14.             redirect_to($NewLocation);    
    15.             exit ();
    16.                
    17.         } else {
    18.             mysqli_rollback($connection);
    19.             $entry = 'id = ' . $_SESSION["id"] . ' Rollback при записи ' . $_SESSION["grp_name"];
    20.             write_to_log($entry);
    21.  
    22.             $NewLocation = "mytable.php?id=" . $_SESSION["id"];
    23.             redirect_to($NewLocation);    
    24.             exit();
    25.         }
    26.     }
    Что значит нажать несколько раз сабмит пока форма исчезнет? Как я понимаю, после нажатия сабмит идет выполнение необходимого кода и уход на другую страницу. И массив пост перестает существовать, точнее на новой странице он другой.
     
  5. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.823
    Симпатии:
    736
    Адрес:
    Татарстан
    При нажатии на сабмит идёт запрос пост или гет по определенному адресу указанному в экшене, отработка сценария. Если плохая связь или сервер тупит - до момента пока прийдёт ответ от сервера, можно успеть ещё раз отправить запрос, та как содержимое экрана ещё все то же - с формой. Особенно если плохой канал связи и оператор быстро шлёпает данные. Проверка на допустимый интервал обычно спасает
     
  6. savsoft

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

    С нами с:
    1 фев 2017
    Сообщения:
    96
    Симпатии:
    2
    А разве уход на другую страницу и exit() не помогают? Да, проблема проявлялась при зависании браузера из-за мобильного интернета.
     
  7. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.823
    Симпатии:
    736
    Адрес:
    Татарстан
    повторная отправка происходит ДО того как сервер отработал и выдал что-то другое на экран, если быть ловким - и плохой инет - можно и 3-4 раза отправить

    Перед записью - находите последнюю запись данного пользователя - проверяете разницу между ней и текущим временем - если меньше 2 сек например - явно дубль
     
  8. savsoft

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

    С нами с:
    1 фев 2017
    Сообщения:
    96
    Симпатии:
    2
    По специфике работы не может быть в один день и в одно время одинаковых записей у одного пользователя. То есть можно просто проверять на существование записи.

    P.S. А можно перед вызовом скрипта с формой обнулять поле флага в сессии, а при записи проверять флаг, если null - сохраняем значение флага в сессии и пишем данные в базу иначе выход?
     
  9. machetero

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

    С нами с:
    25 окт 2014
    Сообщения:
    499
    Симпатии:
    21
    А по факту в бд у пользователя появляется две записи с одинаковым DateTime или Timestamp ?
     
  10. savsoft

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

    С нами с:
    1 фев 2017
    Сообщения:
    96
    Симпатии:
    2
    Это уже я понял, пока нет ответа от сервера, то можно добавить и дубль.

    А если перед вызовом скрипта с формой обнулять поле флага в сессии, а при записи проверять флаг, если null - сохраняем значение флага в сессии и пишем данные в базу иначе выход?
     
  11. acso

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

    С нами с:
    15 апр 2010
    Сообщения:
    150
    Симпатии:
    25
    Адрес:
    Одесса
    А что мешает повесить на форму событие onsubmit, в котором "поднимать флаг" о том, что отправка данных уже происходит. Ещё раз жмем отправку, а облом - флаг уже поднят. Немножко скрипта должно скрасить обстановку)
     
    citikot нравится это.
  12. savsoft

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

    С нами с:
    1 фев 2017
    Сообщения:
    96
    Симпатии:
    2
    Хотя почему будет дубль? Пусть скрипт не получил ответ от сервера и будет выполнен второй раз. Первый раз добавится запись в базу, а во второй раз нет.
    --- Добавлено ---
    Мешает незнание JS.
     
  13. acso

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

    С нами с:
    15 апр 2010
    Сообщения:
    150
    Симпатии:
    25
    Адрес:
    Одесса
    Как-то так:
    Код (Text):
    1. <form onsubmit="send(this); return false">
    2. ...
    3. </form>
    4.  
    5. <script>
    6.  
    7. var inProgress = false;
    8.  
    9. function send(f) {
    10.   if (!inProgress) {
    11.     inProgress = true;
    12.     f.submit();
    13.   }
    14. }
    15.  
    16. </script>
     
  14. savsoft

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

    С нами с:
    1 фев 2017
    Сообщения:
    96
    Симпатии:
    2
    Спасибо. А то я не веб-программист. Как решить задачу для меня не проблема, но хотелось бы это сделать правильно, как для веб-программирования, а не обходными путями. А осваивать JS все равно придется. У заказчика аппетит пришел во время еды. Он все больше функций хочет переложить на пользователей со смартфонами и планшетами.
     
  15. acso

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

    С нами с:
    15 апр 2010
    Сообщения:
    150
    Симпатии:
    25
    Адрес:
    Одесса
    Да я вообще делфист)) Увлекся с 10-ку лет назад php, js, jquery, css, etc. После строгого Делфи просто тащусь.
    --- Добавлено ---
    Ах да, для "спасибо" существует кнопочка)
     
    savsoft нравится это.
  16. savsoft

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

    С нами с:
    1 фев 2017
    Сообщения:
    96
    Симпатии:
    2
    Сейчас найду.
     
  17. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.823
    Симпатии:
    736
    Адрес:
    Татарстан
    минус решения на js - если js будет отключен пользователем... (хотя щас такое редкость)
    ну и если это некое АПИ для моб приложения - там тоже может и не быть js и формы как таковой
     
    citikot нравится это.
  18. acso

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

    С нами с:
    15 апр 2010
    Сообщения:
    150
    Симпатии:
    25
    Адрес:
    Одесса
    Ну так обязать пользователей данного продукта не отключать js, тем более этот проект не для широких масс.
    Или, как вариант для андроид-устройств, скачать Android Studio, написать простейший проект с формой, на которую кинуть браузер, настроенный на адрес с проектом. Открыл приложение - попал на страничку, запостил инфу на сервер.
    Вариант посложнее: все та же Android Studio, форма с компонентами, чекбоксами для ввода инфы, нажали "отправить" и данные через http-компонент улетели на сервер.
    Только в этих случаях, особенно во втором, придется заняться изучением джавы)
    Можно пойти еще дальше и установить тот же Embarcadero Delphi XE10 Berlin, написать проект, скомпилировать его под разные платформы (windows mobile, android, ios) для пользователей с разными операционными системами и девайсами. Вот только придется изучать еще один язык программирования, причем не самый легкий.
    Либо не мучать головной мозг и пятую точку, а просто включить js))