@novichok2020 said in Как сделать, чтобы браузеры автоматически отображались в режиме запуска(есть скрин):
@UserTrue Можно поподробнее, а то я не догоняю)
https://wiki.bablosoft.com/web-interface/#/inspectingbrowser?id=method-showbrowser
@Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:
@sergerdn Честно говоря не понял.
Задача такая. Есть многопоток. Каждый поток пытается ухватить запись, и чтоб другие ее не трогали.
Мой вариант - сразу лочить не залоченную запись. И дальше с ней работать.
Ваш вариант проще?
Есть очень простой вариант делать SELECT FOR UPDATE .
То есть:
used, по умолчанию 0used 0 и СРАЗУ в это же запросе менять used на 1. Это как раз делает SELECT FOR UPDATE .Я так делал, там будут нюансы, связанные с множеством блокировок, но если нет стопицот запросов в секунду, они будут незаметны. Так как SELECT FOR UPDATE залочит всю таблицу на INNODB.
https://dev.mysql.com/doc/refman/8.0/en/select.html
@Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:
@sergerdn Жесть, а зачем всю таблицу то лочить? Я привел пример с полем, когда вообще ничего не лочится. Просто запись выподает из выборки остальных запросов...
Ну оно вот так работает, точнее работало когда то. Сейчас не могу ручаться на 100%. В сфере применения BAS это будет незаметно, так как лок таблицы на наносекунду по время выполнения запроса не повлияет ни на что.
Таблица лочится ТОЛЬКО на время выполнения одного запроса, чтобы взять запись и поменять у нее поле. Как раз, чтобы другие потоки не схватили ее же. Вариантов тут нет, надо лочить.
Может сейчас лочится только конкретная запись, не вся таблица. Пойду как я сам доки почитаю.
Ты дал вариант, при котором другие потоки все таки могут схватить нужную запись.
Поток 1:
А между этими пунктами поток 2 успел схватить ее. Это все ненадежно и добавляет свою логику, вместо SELECT FOR UPDATE, который был придуман ради этого.
@Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:
@sergerdn Жесть, один поток повис, а вся таблица залочена. Это прям майсами какое то...
Сам запрос повис что ли? В честь чего он "повиснет"? И блокировки делаются во время выполнения запроса, когда сам БД его выполняет, а не когда ты его послал.
Спорить не буду, но по мне, проще запись лочить в отдельном поле. Сразу записали, что она не доступна, и дальше делаем что хотим. Переодически после остановки чистить, чтоб хвостов при отвалах не было.
@Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:
Спорить не буду, но по мне, проще запись лочить в отдельном поле. Сразу записали, что она не доступна, и дальше делаем что хотим. Переодически после остановки чистить, чтоб хвостов при отвалах не было.
Логика, что ты предложил, работает не так, как ты от нее ожидаешь. Другие потоки могут схватить запись в ненужный тебе момент. Я отредактировал комментарий выше, где описал ситуацию. Ты фактически пытаешься сделать в коде то, что было уже придумано разработчиками БД.
Все мы строим велосипеды, это частое явление.
@Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:
@sergerdn В смысле? Если запрос идёт с проверкой на поле Лок? Каждый запрос многопотока - проверяет есть ли в поле Лок 1 - они все в очереди. Первый записал, второй не взял....
Есть вариант, что я неправильно тебя понял. Напиши последовательность sql запросов.
Обновляем запись в которой поле Лок =0 меняем на 1, в ответе получили айди записи? Все делаем с ней что хотим. Другой поток ее уже не трогает, так как она не попадает в условие выборки.
@Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:
Обновляем запись в которой поле Лок 0 меняем на 1, в ответе получили айди записи? Все делаем с ней что хотим. Другой поток ее уже не трогает, так как она не попадает в условие выборки.
Дай пример запроса UPDATE, где ты в ответе получаешь id обновленной записи. Потому что у меня какая-то другая БД.
MariaDB [wordpress]> select * from wp_users;
+----+------------+------------------------------------+---------------+--------------------+-------------------------+---------------------+---------------------+-------------+--------------+
| ID | user_login | user_pass | user_nicename | user_email | user_url | user_registered | user_activation_key | user_status | display_name |
+----+------------+------------------------------------+---------------+--------------------+-------------------------+---------------------+---------------------+-------------+--------------+
| 1 | moderator | $P$B/qpWWZ5C./khtr3h03W5S2sEbvW/ | moderator | ghtrhgtrhtrhtr@gmail.com | https://coolwp.com | 2021-11-12 21:16:43 | | 0 | moderator |
+----+------------+------------------------------------+---------------+--------------------+-------------------------+---------------------+---------------------+-------------+--------------+
1 row in set (0.000 sec)
MariaDB [wordpress]> update wp_users set user_email="blaaaa@local";
Query OK, 1 row affected (0.001 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [wordpress]>
@Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:
@sergerdn индекс есть?
CREATE TABLE `wp_users` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_login` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`user_pass` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`user_nicename` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`user_email` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`user_url` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`user_registered` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`user_activation_key` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`user_status` int(11) NOT NULL DEFAULT 0,
`display_name` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
PRIMARY KEY (`ID`),
KEY `user_login_key` (`user_login`),
KEY `user_nicename` (`user_nicename`),
KEY `user_email` (`user_email`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
@Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:
@sergerdn Завтра гляну, с телефона сам понимаешь.
Не понимаю, так как мне неизвестно, чтобы UPDATE возвращал что-то сверх того, что я дал выше. Я понимаю, что я не DBA и легко могу не знать что-то и это прям нормально. Всего знать невозможно. Поэтому я и попросил пример запроса UPDATE , где он возвращает id обновленных записей.
Следующим запросом можно получить инфу, что обновилось, но это будет следующий запрос и мы опять наткнулись, что другой поток может между двумя запросами вмешаться и сделать свою работу. Тогда мы получим не то, что ожидаем.
Щас глянуть не могу, что он возвращает в ответ, но можно писать ведь не 1, а номер потока к примеру, или рендом. И по этому числу искать запись. Проверю завтра.
@Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:
Щас глянуть не могу, что он возвращает в ответ, но можно писать ведь не 1 а номер потока к примеру, или рендом. И по этому числу искать запись. Проверю завтра.
Да многое можно, а потом посмотреть на свой код и понять, что ты сделал функционал SELECT FOR UPDATE.
P.S.
У меня была такая история.
@Bigma said in Как в SQL сделать сразу несколько запросов в одном действии:
@sergerdn Как ты уже написал, она лочит всю таблицу, имей это ввиду.
Я же сам это написал, конечно я имею в виду. И так же добавил, что эта информация может быть устаревшая и надо ее проверять. Может у современных реализаций INNODB немного не так. Может лочится только одна запись в таблице на чтение. Чтобы другой поток не захватил ее.
Под капотом БД многое что делается, другое дело, что ты не знаешь об этом и "спишь спокойно".