Как заблокировать одну строку
У меня есть таблица user
С полем lastusedecnumber
.
Мне нужно получить доступ и увеличить lastusedecnumber
.
В течение этого времени доступа мне нужно заблокировать эту конкретную пользовательскую строку (а не всю таблицу).
Как мне это сделать?
Тип таблицы - MyISAM
.
5 ответов:
MySQL использует только блокировку на уровне таблиц из таблиц MyISAM. Если вы можете, переключитесь на InnoDB для блокировки уровня строки.
Вот ссылка на сайт MySQL, описывающий блокировки, установленные SQL-операторами для таблиц InnoDB. http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html
Вроде поздно, но надеюсь, что это кому-то поможет:
UPDATE user SET lastusedecnumber = LAST_INSERT_ID(lastusedecnumber + 1); SELECT LAST_INSERT_ID();
Даст вам атомарное приращение lastusedecnumber и возможность считывать новое значение поля
lastusedecnumber
(после приращения) с помощьюSELECT LAST_INSERT_ID()
.
В качестве обходного пути вы можете добавить столбец в таблицу, например
locked TINYINT(1)
- всякий раз, когда вы хотите, чтобы строка была заблокирована, вы устанавливаете ее в1
. Когда вы теперь пытаетесь получить доступ к этой строке, первое, что вы делаете, - это проверяете, установлены ли поляlocked
.Чтобы разблокировать строку, просто установите ее в
0
снова. Не очень хороший, но очень простой обходной путь.
Мне не хотелось конвертировать всю мою базу данных из myisam. Поэтому я просто пытаюсь создать новую таблицу с именем, основанным на идентификаторе записи, которую я хочу заблокировать. Если создать таблицу успешно, выполните мою работу и удалите таблицу в конце. Если создать таблицу не удалось, остановитесь.
Лучшим обходным путем является создание столбца, содержащего метку времени. Всякий раз, когда вы хотите заблокировать строку, вы обновляете ее до текущего времени. Чтобы разблокировать обновление на время не менее x минут в прошлом. Затем, чтобы проверить, заблокирован ли он, проверьте, что отметка времени по крайней мере x минут.
Таким образом, если процесс завершается сбоем (или пользователь никогда не завершает свою работу), блокировка фактически истекает через x минут.