Как определить залочена ли таблица другим процессом?

confguru

ExAdmin
Команда форума
Как определить залочена ли таблица другим процессом?

Как определить залочена ли таблица другим процессом?

Есть скрипт в кроне - который делает установку статуса.
Делает LOCK
Как мне определять что он сейчас уже сделал LOCK
и сказать пользователю - типа подождите...
 

Апельсин

Оранжевое создание
admin, просто взять и проверить - никак не сделаешь.
т.е. либо надо самому изобретать флаг что таблица залочена, либо пользоваться функциями GET_LOCK()/IS_FREE_LOCK()/RELEASE_LOCK().
 

confguru

ExAdmin
Команда форума
Т.е.

[sql]
GET_LOCK('my_cron_working',10);
LOCK TABLES trans READ, customer WRITE;
SELECT SUM(value) FROM trans WHERE customer_id=some_id;
UPDATE customer SET total_value=sum_from_previous_statement
WHERE customer_id=some_id;
UNLOCK TABLES;
RELEASE_LOCK('my_cron_working');
[/sql]

А проверять IS_FREE_LOCK('my_cron_working') ?

=========================================
GET_LOCK(str,timeout)

Пытается осуществить блокировку по имени, которое заданно в строке str, с временем ожидания в секундах, указанном в аргументе timeout. Возвращает 1, если блокировка осуществлена успешно, 0 - если закончилось время ожидания для данной попытки, или NULL, если возникла ошибка (такая как отсутствие свободной памяти или уничтожение потока командой mysqladmin kill).

Блокировка снимается при выполнении команды RELEASE_LOCK(), запуске новой команды GET_LOCK() или при завершении данного потока. Эту функцию можно использовать для осуществления блокировок уровня приложения или для моделирования блокировки записи. Функция блокирует запросы других клиентов на блокировку с тем же именем; клиенты, которые используют согласованные имена блокировок, могут применять эту функцию для выполнения совместного упредительного блокирования:


mysql> SELECT GET_LOCK("lock1",10);
-> 1
mysql> SELECT IS_FREE_LOCK("lock2");
-> 1
mysql> SELECT GET_LOCK("lock2",10);
-> 1
mysql> SELECT RELEASE_LOCK("lock2");
-> 1
mysql> SELECT RELEASE_LOCK("lock1");
-> NULL


Обратите внимание: повторный вызов функции RELEASE_LOCK() возвращает NULL, поскольку блокировка lock1 была автоматически выполнена вторым вызовом функции GET_LOCK().


RELEASE_LOCK(str)

Снимает блокировку, указанную в строке str, полученной от функции GET_LOCK(). Возвращает 1 если блокировка была снята, 0 - если такая блокировка уже поставлена в другом соединении (в этом случае блокировка не снимается) и NULL, если блокировки с указанным именем не существует. Последнее может произойти в случае, когда вызов функции GET_LOCK() не привел к успешному результату или данная блокировка уже снята. Функцию RELEASE_LOCK() удобно использовать совместно с командой DO. See Раздел 6.4.10, «Синтаксис оператора DO».


IS_FREE_LOCK(str)

Проверяет, свободна ли блокировка по имени str (т.е. не установлена). Возвращает 1 если блокировка свободна (никто не поставил таковую). Возвращает 0 если блокировка установлена и NULL в случае ошибки (например, при неправильных аргументах).
 

Апельсин

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

confguru

ExAdmin
Команда форума
Апельсин
timeout - это получается время жизни флага?

Оригинал - намного лучше получется.. :)

GET_LOCK(str,timeout)
Tries to obtain a lock with a name given by the string str, with a timeout of timeout seconds
 

Wicked

Новичок
извиняюсь за грэйв диггинг, но тут явно не то написано :)

[quute]Returns 1 if the lock was obtained successfully, 0 if the attempt timed out (for example, because another client has previously locked the name)... If you have a lock obtained with GET_LOCK(), it is released when you execute RELEASE_LOCK(), execute a new GET_LOCK(), or your connection terminates (either normally or abnormally).[/QUOTE]
Ничего про то, что timeout - это время жизни флага - нет. Timeout тут - это время, которое отводится на попытку получить лок.
 

fixxxer

К.О.
Партнер клуба
наиболее правильным решением мне кажется написание хранимой процедуры (mysql 5 required - а хватит юзать рухлядь) для lock/unlock/is_locked и соответствущего возведения флагов. лучше это хотя бы тем, что можно лочить сразу несколько таблиц в одной транзакции, и проверять всё махом.

хранить флаги логично в таблице типа engine=memory.
 
Сверху