2012-02-04 14 views
10

मेरे पास एक PHP स्क्रिप्ट है जो एक SELECT क्वेरी चलाती है तो तुरंत रिकॉर्ड हटा देती है। ऐसी कई मशीनें हैं जो एक ही php फ़ाइल को पिंग कर रही हैं और उसी तालिका से डेटा ला रही हैं। प्रत्येक रिमोट मशीन एक क्रॉन नौकरी पर चल रही है।फिर चयन करें MySQL रिकॉर्ड

मेरी समस्या यह है कि कभी-कभी यह ठीक से हटाने में असमर्थ है क्योंकि मशीनों में से कुछ ठीक उसी समय पिंग करते हैं।

मेरा सवाल यह है कि, मैं डेटाबेस से एक रिकॉर्ड कैसे चुन सकता हूं और अगली मशीन इसे पकड़ने से पहले इसे हटा देता हूं। अभी के लिए मैंने अभी थोड़ी देर दे दी है लेकिन यह बहुत अच्छी तरह से काम नहीं कर रहा है। मैंने लेनदेन का उपयोग करने की कोशिश की, लेकिन मुझे नहीं लगता कि यह यहां लागू होता है।

<?php 

$query = "SELECT * FROM `queue` LIMIT 1"; 
$result = mysql_query($query) or die(mysql_error()); 

while($row = mysql_fetch_array($result)){ 
    $email = $row['email']; 
    $campaign_id = $row['campaign']; 
} 

$queryx = "DELETE FROM `queue` WHERE `email` = '".$email."'"; 
$resultx = mysql_query($queryx) or die(mysql_error()); 

?> 

सच सहायता की सराहना:

यहाँ मेरी स्क्रिप्ट का एक उदाहरण टुकड़ा है।

+2

यह कैसे लागू नहीं होता है? यह * बिल्कुल * लगता है जैसे लेनदेन के लिए अच्छा है। – mpen

+0

क्या आपको संग्रहीत प्रक्रियाओं का उपयोग करने की अनुमति है? – dvicino

+0

@ मार्क - क्या लेनदेन 'SELECT को ऑपरेटिंग से रोकता है? मैं सोच रहा हूं कि यह समस्या नहीं हो सकती है।@ जॉन - यदि ये 'क्रॉन' द्वारा चलाए जाते हैं, तो 'मर (mysql_error())' बिंदु क्या है? किसी फ़ाइल या किसी चीज़ में त्रुटि लॉग क्यों नहीं करें? –

उत्तर

-3

अपने हटाए गए प्रश्नों को थोड़ी देर के अंदर रखें, बस आप कभी भी अपने चयन से सीमा को बढ़ाना चाहते हैं।

<?php 
$query = mysql_query("SELECT * FROM `queue` LIMIT 1") or die(mysql_error()); 

while($row = mysql_fetch_array($query)){ 
    mysql_query("DELETE FROM `queue` WHERE `email` = '" . $row['email'] . "' LIMIT 1") or die(mysql_error()); 
} 
?> 

ऊपर कोड चल रहा है के रूप में सिर्फ एक ही होगा:

mysql_query("DELETE FROM `queue` LIMIT 1") or die(mysql_error()); 

अपने हटाएँ क्वेरी का उपयोग कर, अगर ईमेल क्षेत्र को खाली है, यह सभी पंक्तियों एक रिक्त ईमेल है कि नष्ट करेगा सावधान रहें। कई पंक्तियां हटाए जाने से बचने के लिए अपनी हटाई गई क्वेरी में LIMIT 1 जोड़ें।

एक यादृच्छिक देरी जोड़ने के लिए, आप स्क्रिप्ट के शीर्ष करने के लिए एक sleep जोड़ सकता है,

जैसे:

<?php 
$seconds = mt_rand(1,10); 
sleep($seconds); 
?> 
+1

मुझे नहीं पता कि यह दौड़ की स्थिति/विवाद की समस्या से छुटकारा पाने जा रहा है, यह "संभव" गतिविधि की मात्रा को "छोटा" करता है। यह कुछ मामलों में काम कर सकता है, लेकिन अभी भी विसंगतियां हो सकती हैं। नोट, साथ ही, चूंकि 'LIMIT 1' है, 'जबकि()' अनिवार्य है। तो मुझे नहीं पता कि यह वास्तव में अंत में उत्पादक कुछ भी करेगा ... –

+0

यदि वह कभी भी 1 से अधिक परिणाम में SELECT को बदलने का निर्णय लेता है, तो हटाई गई क्वेरी केवल पहले परिणाम पर ही चलती है। तो अंत में यह अधिक उत्पादक है और लूप के बाहर DELETE होने के लिए कोई अलग 'संसाधन वार' नहीं है। –

+0

"अगर"? अगर बहुत सारे हैं। यदि ओपी एक कतार पॉपिंग कर रहा है, तो मुझे लगता है कि यह केवल एक होने का मतलब है। बिंदु अभी भी वही है (और बाद में संसाधित परिणामों के लिए कई परिणाम लौटाए गए हैं)। –

6

अच्छी तरह से मैं मेज ताले का प्रयोग करेंगे read more here

लॉकिंग सुरक्षित है और एक ग्राहक सत्र पर लागू होता है। एक टेबल लॉक केवल अन्य सत्रों द्वारा अनुचित पढ़ने या लिखने के खिलाफ सुरक्षा करता है।

1

एक अद्यतन क्वेरी चलाएं जो आपके चयन करने से पहले कुंजी को बदल देगा। इस नई कुंजी द्वारा चयन करें, whicj केवल उसी सत्र में जाना जाता है।
यदि तालिका innoDB है तो रिकॉर्ड लॉक हो गया है, और जब इसे रिलीज़ किया जाएगा, तो अन्य चयन रिकॉर्ड नहीं पाएंगे।

+1

[चयन करें ... अद्यतन और चयन के लिए ... साझा मोड लॉकिंग लॉक में लॉक] (http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html)। –

+0

केवल मेरे प्रश्न के साथ मेरा प्रश्न है, क्या आप 'चयन ... अद्यतन के लिए' हटा सकते हैं? या क्या आपको पहले अनलॉक करना है (और इसलिए जहां हमने शुरू किया था)? –

3

इस प्रकार आप सबक्वेरी का उपयोग करना चाहिए ...

<?php 

$queryx = "DELETE FROM `queue` WHERE `email` IN (SELECT email FROM `queue` LIMIT 1)"; 
$resultx = mysql_query($queryx) or die(mysql_error()); 

?> 

* ध्यान दें: हमेशा ही क्षेत्रों आप चाहते हैं का चयन करें ... का चयन से बचने की कोशिश * ... यह नीचे प्रदर्शन धीमी हो जाएगी

+0

दिलचस्प। यदि बिंदु "यादृच्छिक" ईमेल द्वारा सभी पंक्तिबद्ध पंक्तियों को साफ़ करना है, तो यह काम कर सकता है। –

+0

इसके अलावा, 'चयन *' बहुत अच्छी सलाह है। 'ईमेल चुनें 'पर्याप्त होना चाहिए। –

+0

आप एक सबक्वायरी के अंदर LIMIT का उपयोग नहीं कर सकते हैं। अन्यथा यह वही था जो मैं करने की कोशिश कर रहा था। – john

4

आप MariaDB 10 उपयोग कर रहे हैं:

DELETE FROM `queue` LIMIT 1 RETURNING * 

Documentation

+0

यह अच्छा है, लेकिन केवल मारियाडीबी 10.0.5 या नए में काम कर रहा है –

संबंधित मुद्दे