Обучение/Помощь новичкам | Блокировка БД
А что бы выбрал(а) ты? (Открытое голосование)
lastInsertId() (1 чел. - 100 %)
LOCK TABLES (0 чел. - 0 %)
Всего проголосовало: 1 чел.
Допустим у меня такой пример
Возможен ли вариант что во время "sleep" какой-нибудь другой юзер добавит еще одну свою запись и я в $last получу левый id ? Если да, то как этого избежать? Как заблокировать таблицу от изменений во время работы скрипта?
php
<?php
db::exec("INSERT INTO log(ip, action) VALUES ('xxx', 'yyy')";
sleep(rand(10, 60)); # Некая ресурсоёмкая задача
# А тут мне надо получить id этой записи
$last = db::fetch("SELECT id FROM log ORDER BY id DESC LIMIT 1");Возможен ли вариант что во время "sleep" какой-нибудь другой юзер добавит еще одну свою запись и я в $last получу левый id ? Если да, то как этого избежать? Как заблокировать таблицу от изменений во время работы скрипта?
Те же яйца только в профиль. Я про блокировку спросил
Те же яйца только в профиль. Я про блокировку спросил
Потом UNLOCK после выполнения
Допустим у меня такой пример
php
<?php
db::exec("INSERT INTO log(ip, action) VALUES ('xxx', 'yyy')";
sleep(rand(10, 60)); # Некая ресурсоёмкая задача
# А тут мне надо получить id этой записи
$last = db::fetch("SELECT id FROM log ORDER BY id DESC LIMIT 1");Возможен ли вариант что во время "sleep" какой-нибудь другой юзер добавит еще одну свою запись и я в $last получу левый id ? Если да, то как этого избежать? Как заблокировать таблицу от изменений во время работы скрипта?
php
<?php
db::beginTransaction();
db::exec("INSERT INTO log(ip, action) VALUES ('xxx', 'yyy')";
sleep(rand(10, 60));
$last = db::fetch("SELECT id FROM log ORDER BY id DESC LIMIT 1");
db::commit();________
посл. ред. 16.08.2023 в 11:19; всего 1 раз(а); by mrcatoff
Вот это походу то что надо. А если где-то между локом и анлоком скрипт сдохнет (например из-за fatal error), то база останется заблокированной?
Адм
(16 авг 2023, в 11:19)https://www.php.net/manual/en/pdo.begintransaction.php
php
<?php
db::beginTransaction();
db::exec("INSERT INTO log(ip, action) VALUES ('xxx', 'yyy')";
sleep(rand(10, 60));
$last = db::fetch("SELECT id FROM log ORDER BY id DESC LIMIT 1");
db::commit();________
посл. ред. 16.08.2023 в 11:36; всего 2 раз(а); by Something
Вот это походу то что надо. А если где-то между локом и анлоком скрипт сдохнет (например из-за fatal error), то база останется заблокированной?
Ты повесил замок, пока не откроешь не попадешь
Те же яйца только в профиль. Я про блокировку спросил
https://ru.stackoverflow.com/questions/453648/Какой-id-верн...nsertid-из-pdo
Ты не только про блокировку спрашивал
Я ответила оптимальный вариант для получения ид
Зачем блокировать всю таблицу?
________
посл. ред. 16.08.2023 в 14:46; всего 1 раз(а); by Лара
Допустим у меня такой пример
php
<?php
db::exec("INSERT INTO log(ip, action) VALUES ('xxx', 'yyy')";
sleep(rand(10, 60)); # Некая ресурсоёмкая задача
# А тут мне надо получить id этой записи
$last = db::fetch("SELECT id FROM log ORDER BY id DESC LIMIT 1");Возможен ли вариант что во время "sleep" какой-нибудь другой юзер добавит еще одну свою запись и я в $last получу левый id ? Если да, то как этого избежать? Как заблокировать таблицу от изменений во время работы скрипта?
Чтобы избежать этой ситуации, ты можеш воспользоваться механизмами транзакций и блокировок в базе данных. В большинстве систем управления базами данных (СУБД) есть поддержка транзакций и блокировок, которые позволяют контролировать доступ к данным в многопользовательской среде.
Тебе нужно выполнить следующие шаги:
Начать транзакцию: Перед выполнением INSERT запроса начни транзакцию. Это предотвратит доступ других пользователей к данным до завершения транзакции.
Выполнить INSERT внутри транзакции: Выполните INSERT запрос внутри начатой транзакции.
Выполнить SELECT внутри транзакции: Также выполните SELECT запрос для получения ID внутри транзакции.
Завершить транзакцию: После выполнения всех операций (включая sleep), заверши транзакцию. Это позволит другим операциям получить доступ к данным.
Примерно так это может выглядеть в коде:
php
<?php
$db = new PDO("your_database_connection_details");
try {
$db->beginTransaction();
$insertQuery = "INSERT INTO log(ip, action) VALUES ('xxx', 'yyy')";
$db->exec($insertQuery);
sleep(rand(10, 60)); // Некая ресурсоёмкая задача
$selectQuery = "SELECT id FROM log ORDER BY id DESC LIMIT 1";
$last = $db->query($selectQuery)->fetchColumn();
$db->commit();
} catch (Exception $e) {
$db->rollBack();
// Обработка ошибки
}
?>Здесь используем транзакции для обеспечения целостности данных и блокировки таблицы во время выполнения операций. Важно отметить, что использование транзакций может варьироваться в зависимости от типа базы данных, который ты используете.
Стр.: 1, 2