it-swarm.com.de

Was ist im Allgemeinen der Zweck der Drupal DB Semaphore Table?

Ich verstehe den Zweck eines Semaphors in IPC Programmierung, aber ich finde keine gute - oder keine - Erklärung für diesen Tabellenzweck.

9
Mike

Die Semaphorentabelle wird von Sperrmechanismus verwendet, der standardmäßig von Drupal implementiert ist. Es unterscheidet sich nicht von dem in der Programmierung üblichen Sperrmechanismus: Ein Wert wird verwendet, um zu überprüfen, ob eine Operation bereits ausgeführt wird, um Konflikte oder Rennen zu vermeiden Bedingungen. Der Unterschied besteht darin, dass die Sperre normalerweise eine Datei ist, während Drupal die Zeile in einer Datenbank verwendet.

Tatsächlich hat der Verriegelungsmechanismus Funktionen, um eine Sperre zu erlangen ( lock_acquire() ) oder zu warten, bis eine Sperre aufgehoben wird ( lock_wait() ). In beiden Fällen wird die Semaphor-Datenbank verwendet.

// 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;

In Drupal können verschiedene Benutzer dieselbe Seite anfordern, was bedeutet, dass verschiedene Threads oder Prozesse denselben Code gleichzeitig ausführen können. Dies kann zu Problemen führen, wenn der Code beispielsweise eine Datenbanktabelle aktualisiert. Die Verwendung von Schlössern ist ein Weg, um dies zu vermeiden und Probleme zu verursachen.

Der Grund, warum eine Datenbanktabelle verwendet wird, ist einfach, dass Drupal erfordert, dass ein Datenbankmodul funktioniert; die Verwendung einer Datenbanktabelle auch für den Sperrmechanismus ist eine Möglichkeit, die Anforderungen zu reduzieren. Der Sperrmechanismus könnte implementiert werden Verwenden Sie auch die APCu-Erweiterung, und wenn ich mich richtig erinnere, gibt es ein Modul, das dies tut.

11
kiamlaluno

Die Antwort von @kiamlaluno ist vollständig und perfekt. Aber ich denke, es konzentriert sich darauf, das Konzept/die Verwendung von DB-Locking unter Verwendung von Drupals Semaphoren (brillant) zu erklären.

Ich würde es wiederum wagen, näher an das OP heranzukommen:

Der Zweck der Semaphortabelle ist (wie in der Beschreibung zur Erstellung der Semaphortabelle beschrieben):

Tabelle zum Speichern von Semaphoren, Sperren, Flags usw., die nicht als Drupal -Variablen gespeichert werden können, da sie nicht zwischengespeichert werden dürfen.

Der Zweck dieser Tabelle ist also mehr als nur DB-Sperrmechanismen (soweit ich aus diesem Kommentar verstehen kann), und sie befasst sich auch mit der technischen Anforderung, das Zwischenspeichern von Variablen zu vermeiden.

NB.: Gerne wird ich von jemandem mit mehr Fachwissen zu diesem Thema korrigiert, wenn ich das falsch verstanden habe. Prost!

6