2009-06-18 7 views
5

मैं स्वीकार करूंगा कि मैं पीडीओ और माईएसक्यूएल के आंतरिक कार्यों पर 100% नहीं हूं, इसलिए मैं अपना प्रश्न स्पष्ट करने के लिए एक उदाहरण दूंगा।क्या PHP को PHP में मजबूर करने का कोई तरीका है जब तक कि MySQL लेनदेन के साथ समाप्त न हो जाए?

मैं बल्कि कच्चे ब्राउज़र आधारित रणनीति गेम बना रहा हूं, क्योंकि मुझे लगता है कि यह PHP और डेटाबेस सीखने का एक मजेदार तरीका है। जब मैं एक अप्रत्याशित बग में आया तो मैं युद्ध स्क्रिप्ट को बग-परीक्षण कर रहा था। मैं हर मिनट एक स्क्रिप्ट कॉल करने के लिए क्रॉन जॉब्स का उपयोग करता हूं, इस तरह कुछ दिख रहा हूं:

$ sql = "सक्रियता से सेना_आईडी चुनें जहां आगमन = 0;";

foreach($dbh->query($sql) as $row) 
    { 

     battleEngine($row["army_id"]); 

    } 

जब बुनियादी गणना (सेना का बचाव बनाम सेना पर हमला कर) किया जाता है, डेटाबेस में छह टेबल अद्यतन किया जाता है। मुझे जिस समस्या का सामना करना पड़ता है वह यह है कि जब मैं एक ही मिनट में एक ही लक्ष्य में कई हमले करता हूं, तो हर अब और फिर उन हमलों में से एक अप्रचलित डेटाबेस जानकारी प्राप्त करता है (एक चरम मामले में, हमले # 10 ने उसी तालिका को हमले के रूप में लाया # 5) ।

मुझे लगता है कि ऐसा होता है क्योंकि स्क्रिप्ट डेटाबेस से तेज है? अगली $ पंक्ति के साथ फ़ंक्शन को दोहराने से पहले सभी प्रासंगिक जानकारी मौजूद होने तक PHP को प्रतीक्षा करने का कोई तरीका है?

संपादित करें: एमिल शायद सही है। मैं यह सुनिश्चित नहीं कर सकता कि यद्यपि मेरे पीडीओ के लिए शुरुआत के लिए असंभव लगता है कि मेरे लिए startTransaction() और प्रतिबद्ध() के बीच कई कथन पास करने के लिए पर्याप्त समय तक खुला रहता है। हालांकि, एक गंदे पठन अजीब लगता है क्योंकि मैं "दोहराए गए पढ़ने" के साथ इनो डीबी का उपयोग कर रहा हूं। कुछ गूगलिंग सुझाव देते हैं कि दोहराए गए पढ़ने से गंदा पढ़ना असंभव हो जाएगा। थोड़ी देर के लिए खुद को मारने के बारे में सोचने के बाद, मैंने इसके बजाय एक हैक का चयन किया। अभी के लिए, मैंने अपनी स्क्रिप्ट के शीर्ष पर एक विशेष मूल्य के लिए एक अद्यतन दिया है, और दूसरा नीचे बैच (लगभग छः अद्यतन विवरण) के अंत में। फ़ंक्शन चलाने से पहले, मैंने थोड़ी देर() - लूप लगाया है जो जांचता है कि क्या उस विशेष मान को 0 पर सेट किया गया है। यदि ऐसा नहीं है, तो यह 0.01 सेकंड तक सोता है और पुनः प्रयास करें। आउटपुट को देखते हुए, जबकि लूप औसत दो बार दोहराता है, यह सुझाव देता है कि यह वास्तव में काम कर रहा है? यह अभी तक विफल नहीं हुआ है, लेकिन ऐसा इसलिए हो सकता है क्योंकि यह चरम घंटे नहीं है। मैं कल नियमित अंतराल पर फिर कोशिश करूंगा। मुझे पता है कि कोई भी इस बारे में परवाह नहीं करता है, लेकिन मुझे लगा कि मुझे इस मामले को सिर्फ मामले में बनाना चाहिए। = पी

उत्तर

1

यदि PHP पूरी तरह से प्रतीक्षा करेगा, तो आपको उच्च संख्या में क्रॉन नौकरियां मिलेंगी।

आप वास्तव में चाहते हैं कि एनाक्रॉन की तरह कुछ उपयोग करना है, यह सुनिश्चित करने के लिए कि किसी भी पल में स्क्रिप्ट का केवल एक उदाहरण चलता है। इसके अलावा आप निम्न की तरह कुछ कर सकते हैं:

<?php 

    if (file_exists('/tmp/myscriptlock')) exit(); 
    touch('/tmp/myscriptlock'); 

    // do your stuff 

    unlink('/tmp/myscriptlock'); 
+0

खराब प्रारूपण के लिए srry – Evert

+1

इसके लिए एक MySQL लॉक का उपयोग करना बेहतर होगा, इस तरह यदि नौकरी और इस प्रकार कनेक्शन मर जाता है तो लॉक स्वचालित रूप से रिलीज़ हो जाता है। http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock –

1

जो आप देख रहे हैं उसे "गंदे पढ़ने" कहा जाता है। InnoDB का उपयोग करें और isolation level क्रमबद्ध करने के लिए सेट करें। तब वह लेन-देन ब्लॉकों में सभी प्रश्नों लपेट:

$dbh->beginTransaction(); 
// run queries 
$dbh->commit(); 
0

मेरे प्रारंभिक सोचा सरल mysql लिखने ताले था, लेकिन मैं काफी अच्छी तरह से समस्या समझ में नहीं आता। किसी भी मामले में यह मदद कर सकता है: http://www.perplexedlabs.com/2008/02/06/mutex-with-php-and-mysql/

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

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