답변:
세마포어 테이블은 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의 세마포어를 사용하여 db 잠금의 개념 / 사용법을 설명하는 데 중점을두고 있다고 생각합니다.
나는 다시 영업에 가까워 질 것이다.
세마포어 테이블의 목적은 다음과 같습니다 (세마포어 테이블 작성 설명에 설명 된대로).
Drupal 변수로 저장 될 수없는 세마포어, 잠금, 플래그 등을 보유하기위한 테이블입니다.
따라서 해당 테이블의 목적은 단순한 DB 잠금 메커니즘 이상이며 (지금까지 해당 의견에서 이해할 수 있음) 변수 캐싱을 피하기위한 기술적 요구 사항도 해결합니다.
NB : 내가 잘못 알고 있다면이 주제에 대해 더 많은 전문 지식을 가진 사람이 기꺼이 시정 할 것입니다. 건배!