Задавайте вопросы, мы ответим
Вы не зашли.
Моя база MySQL состоит из нескольких таблиц (все MyISAM). Одна из них - список зарегистрированных пользователей (USERS), другая - детальная характеристика пользователей (DETAIL_USERS)
При регистрации пользователя по email я блокирую таблицу USERS:
LOCK TABLES users WRITE
для того, чтобы узнать, есть ли уже такой email в ней и, если нет, то произвести регистрацию. И случайно я забыл снять эту блокировку. Так вот следующая команда, делающая вставку в DETAIL_USERS почему-то не смогла выполниться. Объясните мне, пожалуйста, в чем дело?
Неактивен
Признаться, не понимаю для чего ее блокировать. Уж больно радикально. У вас проверка идет довольно быстро, только на одну запись (limit 1).
Даже смысла ставить высокий приоритет не вижу
Напишите запросы, без них сложно.
Неактивен
Между запросом на существование email и регистрацией нового пользователя есть, пусть и очень маленький, риск, что произойдет вот такая ситуация:
Пользователь FIRST делает запрос на существование email@mail.ru и получает отрицательный результат и право на регистрацию. И сразу же после него пользователь SECOND тоже делает запрос на существование email@mail.ru и также получает отрицательный результат и право на регистрацию. Пользователь FIRST реализует свое право и регистрирует email@mail.ru. Пользователь SECOND сразу в след за ним также реализует свое право и регистрирует email@mail.ru. Получаем два одинаковых логина в базе. Проблему можно решить, заставив MySQL следить за уникальностью значений данного поля, но на мой взгляд лучшее решение - это просто никому не давать вклиниваться между парой данных запросов. А почему ставлю блокировку WRITE, а не READ - все по той же причине: если второй пользователь сможет прочитать данную таблицу, то получит право на регистрацию, хотя уже другой пользователь сделал такой же запрос и уже получил данное право.
$is_already_registred =$db->query("SELECT email FROM USERS WHERE email='$useremail'");
if (mysql_num_rows($is_already_registred) < 1) {
$db->query("INSERT INTO USERS (email,.......) VALUES
('$useremail', ....)");
$unlock = $db->query("UNLOCK TABLES");/*вот эту строку я сначала забыл*/
.........
.........
$db->query("INSERT INTO detail_users ([list_fields]) VALUES ([list_values])");/*данная строка находится в другом классе, нежели предыдущие и выполняется после них. Если блокировка не была снята, то данная строка не выполняется*/
Неактивен
Для такой задачи - LOCK TABLE - это из пушки по воробьям. Гораздо лучше сделать поле e-mail уникальным, так контроль будет на уровне базы.
Неактивен
Ну допустим, что для данного случая блокировка таблицы - перебор. Вопрос не в этом, а в том, почему блокируется и вторая таблица?
Неактивен
"Пока клиент удерживает явную блокировку, он не может использовать другие таблицы, поэтому блокировать нужно сразу все что понадобится (одним выражением), так как повторное использование оператора LOCK TABLES отменяет сделанные ранее блокировки."
Блокировки в MySQL
Неактивен
Вот это ценная фраза.
Но тогда у меня такой вопрос. Пока клиент удерживает явную блокировку, он не может использовать другие таблицы - это не смертельно. А смогут ли другие пользователи использовать эти другие таблицы (в моем случае при заблокированной USERS будут ли другие пользователи иметь доступ к DETAIL_USERS)?
Неактивен
Смогут.
Неактивен
очень жаль, что в нашей стане большинство книжек сейчас пишется для денег, а не для знаний))))
Вы успокоили мою мятущуюся душу)))
Неактивен