Форум программистов, компьютерный форум, киберфорум
PHP: базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 24.11.2014
Сообщений: 10
MySQL

Как реализовать многопоточное обновление данных без конфликтов?

20.01.2017, 14:51. Показов 1386. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пере до мной встала интересная задача, с которой я не могу справиться.
Условие:
Есть таблица с данными. Нужно в многопоточном режиме последовательно выбирать из таблицы по одной записи и обновлять количество выборов для нее. Каждая запись должна быть выбрана не больше двух раз. Так-же между выбором и обновлением есть микрозадержка.

На практике есть скрипт php, который выполняется в многопоточном режиме и выбирает запись из mysql таблицы innodb, которая была выбрана не более 2-х раз до этого, основываясь на поле count. После выбора записи для нёё, поле count увеличивается на 1.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$connect = mysqli_connect($host, $dbuser, $dbpass);
  if($connect){
    mysqli_select_db($connect, $dbname);
    for ($i = 1; $i <= 10; $i++) {
      //Выбираем подряд записи, у которых count < 2
      $sql = mysqli_query($connect, "SELECT id FROM threadsTest WHERE id >= {$i} AND count < 2 LIMIT 1;");
      if (mysqli_num_rows($sql) > 0){
        $row = mysqli_fetch_assoc($sql);
        //Задержка после выбора 0.1 сек
        usleep(100000);
        //Обновление count
        mysqli_query($connect, "UPDATE threadsTest SET count = count + 1 WHERE id = {$row['id']}");
      }
      
    }
    mysqli_close($connect);
  }
Но очевидно, что в такой ситуации поля выбираются большее количество раз, т.к. апдейт просто не успевает выполнятся и нарушается логика работы.

Моё решение - после выборки создавать дополнительный файл для записи, если его нет и инкрементить в него с блокировкой счетчик выборок. Сразу после выборки проверять этот файл и если счетчик в нём 2, пробовать выбрать следующую запись. Однако у этого способа есть недостаток. Проверка происходит уже после выборки и приходится перебирать намного большее количество записей. В моем тесте это увеличило время работы в 100 раз и это очень зависимо от количества потоков и количества данных в таблице.

Другой вариант - использовать SELECT FOR UPDATE, но тут есть проблема. Выборка последовательная, а MySQL не имеет способа игнорировать заблокированные строки в SELECT. Получается что каждый момент времени активен лишь 1 скрипт. Провёл тест, запустив одновременно 300 скриптов, получилось что каждый скрипт ждёт завершения активного и только после этого выполняется сам, что получается невероятно долго. При этом выполнились только 60, остальные отвалились по таймауту ожидания разблокировки: Lock wait timeout exceeded;

Ещё вариант, считать количество запущенных скриптов, перед каждой выборкой проверять количество данных в таблице и выбирать только из определенного диапазона, доступного конкретному скрипту. Однако в практической задаче, а не в тестовой, каждый скрпт должен иметь доступ ко всем данным таблицы, а не только к части.

Что можно предпринять в такой ситуации, сохранив логику работы и приемлемую скорость выполнения?
Буду рад любым свежим идеям и предложениям

Кому интересно попробовать разобраться в этом, вот тестовый скрипт:
https://yadi.sk/d/mnHA4grn39xBaT

create_table.php - создаёт тестовую таблицу с полями id и count, заполняет её данными
clear_table.php - обнуляет count в тестовой таблице
thread.php - сам скрипт, который делает выборку и инкрементит count
run_threads.sh - bash скрипт, который запускает thread.php в 300 потоков
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.01.2017, 14:51
Ответы с готовыми решениями:

Добавление оперативной памяти, как обойтись без конфликтов?
Стояло 2 оперативки hunix DDR-II PC2-5300U, одна планка полетела, Теперь хочу добавить 1024 или 2048. Какую можно поставить чтоб не...

Как без конфликтов с СКУД получать доступ к её БД из модуля C#
Здравствуйте... Помогите решить проблемку... 1) Имется система контроля и управления доступом ForSec 2.3. Она состоит из 8 модулей,...

Как можно реализовать без setInterval обновление html у пользователя при изменении значения в бд?
Здравствуйте. Подскажите, пожалуйста, как можно грамотно реализовать без setInterval обновление html у пользователя при изменении значения...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.01.2017, 14:51
Помогаю со студенческими работами здесь

Обновление данных в таблице, как правильно реализовать?
Добрый день! Есть таблица, в скриншоте приложил Добавляются данные так: $query = &quot;INSERT INTO purchases VALUES ...

Как реализовать обновление данных в SQL через кнопку на Представлении контроллера
Проект называется &quot;Автоматизация продаж малого предприятия&quot;.5 таблиц - 5 контроллеров. Контроллер на таблицу &quot;Заказы&quot; содержит...

Многопоточное обновление label
Всех приветствую. Есть следующий код с кнопочкой Старт и одним лейблом. Мне необходимо запустить метод main класса potok многопоточно, в...

Многопоточное обновление richTextBox
джентельмены, есть код: foreach (var item in richTextBox1.Lines) { string result = await...

Убрать дубли страниц в htaccess без конфликтов со скриптами
Добрый день! В общем требуется удалить дубли формата index.php и index.php/, то есть все дубли со слешем! Сделал так: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru