Ответы:
Таблица семафоров используется из механизма блокировки, реализованного по умолчанию из Drupal. Он не отличается от обычного механизма блокировки, видимого в программировании: значение используется для проверки того, что операция уже выполняется, чтобы избежать конфликтов или условий гонки. Разница в том, что обычно блокировка - это файл, а Drupal использует строку в базе данных.
Фактически, механизм блокировки имеет функции для получения блокировки ( lock_acquire()
) или ожидания снятия блокировки ( lock_wait()
). В обоих случаях используется база данных семафоров.
// lock_acquire()
// Optimistically try to acquire the lock, then retry once if it fails.
// The first time through the loop cannot be a retry.
$retry = FALSE;
// We always want to do this code at least once.
do {
try {
db_insert('semaphore')
->fields(array(
'name' => $name,
'value' => _lock_id(),
'expire' => $expire,
))
->execute();
// We track all acquired locks in the global variable.
$locks[$name] = TRUE;
// We never need to try again.
$retry = FALSE;
}
catch (PDOException $e) {
// Suppress the error. If this is our first pass through the loop,
// then $retry is FALSE. In this case, the insert must have failed
// meaning some other request acquired the lock but did not release it.
// We decide whether to retry by checking lock_may_be_available()
// Since this will break the lock in case it is expired.
$retry = $retry ? FALSE : lock_may_be_available($name);
}
//lock_may_be_available()
$lock = db_query('SELECT expire, value FROM {semaphore} WHERE name = :name', array(':name' => $name))->fetchAssoc();
if (!$lock) {
return TRUE;
}
$expire = (float) $lock['expire'];
$now = microtime(TRUE);
if ($now > $expire) {
// We check two conditions to prevent a race condition where another
// request acquired the lock and set a new expire time. We add a small
// number to $expire to avoid errors with float to string conversion.
return (bool) db_delete('semaphore')
->condition('name', $name)
->condition('value', $lock['value'])
->condition('expire', 0.0001 + $expire, '<=')
->execute();
}
return FALSE;
В Drupal разные пользователи могут запрашивать одну и ту же страницу, что означает, что разные потоки или процессы могут выполнять один и тот же код в одно и то же время. Это может вызвать проблемы, когда код, например, обновляет таблицу базы данных. Использование блокировок - способ избежать этого, это может вызвать проблемы.
Причина, по которой таблица базы данных используется, заключается в том, что для работы Drupal требуется механизм базы данных; Использование таблицы базы данных также для механизма блокировки - это способ снизить требования. Механизм блокировки также может быть реализован с использованием расширения APCu, и, если я правильно помню, есть модуль, который делает это.
Ответ @kiamlaluno является полным и совершенным. Но я думаю, что он сфокусирован на объяснении (блестяще) концепции / использования блокировки БД с использованием семафоров drupal.
Я бы в свою очередь рискнул приблизиться к ОП:
Назначение таблицы семафоров (как описано в описании создания таблицы семафоров):
Таблица для хранения семафоров, блокировок, флагов и т. Д., Которые нельзя хранить как переменные Drupal, поскольку они не должны кэшироваться.
Итак, цель этой таблицы - не просто механизмы блокировки дБ (насколько я понимаю из этого комментария), а также технические требования избегать кэширования переменных.
NB: Буду рад, если кто-то с большим опытом в этой теме будет исправлен, если я ошибся. Ура!