जवाबों:
सेमाफोर टेबल का उपयोग द्रुपाल से डिफ़ॉल्ट रूप से लागू लॉकिंग तंत्र से किया जाता है। यह प्रोग्रामिंग में देखा जाने वाले लॉकिंग के सामान्य तंत्र से अलग नहीं है: एक ऑपरेशन को सत्यापित करने के लिए एक मूल्य का उपयोग पहले से ही प्रगति पर है, संघर्ष या दौड़ की स्थिति से बचने के लिए। अंतर यह है कि, सामान्य रूप से, लॉक एक फ़ाइल है, जबकि 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;
ड्रुपल में, विभिन्न उपयोगकर्ता एक ही पृष्ठ का अनुरोध कर सकते हैं, जिसका अर्थ है कि विभिन्न धागे या प्रक्रियाएं एक ही समय में एक ही कोड निष्पादित कर सकती हैं। यह समस्या तब हो सकती है जब कोड, उदाहरण के लिए, डेटाबेस तालिका को अपडेट कर रहा हो। ताले का उपयोग करना एक तरीका है जिससे बचने के लिए समस्या हो सकती है।
डेटाबेस तालिका का उपयोग करने का कारण यह है कि ड्रुपल को काम करने के लिए डेटाबेस इंजन की आवश्यकता होती है; लॉकिंग तंत्र के लिए भी डेटाबेस तालिका का उपयोग करना आवश्यकताओं को कम करने का एक तरीका है। लॉकिंग मैकेनिज्म को APCu एक्सटेंशन का उपयोग करके भी लागू किया जा सकता है, और अगर मुझे सही ढंग से याद है, तो ऐसा करने वाला एक मॉड्यूल है।
@Kiamlaluno का उत्तर पूर्ण और परिपूर्ण है। लेकिन, मुझे लगता है कि यह ड्रूपल के सेमाफोर का उपयोग करके डीबी लॉकिंग की अवधारणा / उपयोग (शानदार ढंग से) को समझाने पर केंद्रित है।
मैं बारी उद्यम में ओपी के करीब होता जा रहा हूं:
सेमाफोर टेबल का उद्देश्य (जैसा कि सेमाफोर टेबल निर्माण विवरण में वर्णित है):
सेमाफोर, तालों, झंडों आदि को रखने की तालिका जिसे ड्रुपल चर के रूप में संग्रहीत नहीं किया जा सकता है क्योंकि उन्हें कैश नहीं किया जाना चाहिए।
तो, उस तालिका का उद्देश्य सिर्फ db लॉकिंग मैकेनिज्म से अधिक है (अब तक मैं उस टिप्पणी से समझ सकता हूं), और यह चर के कैशिंग से बचने की तकनीकी आवश्यकता को भी संबोधित करता है।
एनबी: अगर मुझे यह गलत मिला तो इस विषय पर अधिक विशेषज्ञता वाले किसी व्यक्ति द्वारा सही होने पर खुशी होगी। चीयर्स!