2011-08-11 15 views
5

के लिए एक का चयन क्वेरी में पंक्तियों ताला लगा तो मैं घर साइटों में के रखरखाव के लिए एक सरल वेबसाइट क्रॉलर लिख रहा हूँ। यह प्रत्येक लिंक के माध्यम से जाएगा, जैसा कि उन्हें पाता है, शीर्षक और एच 1 टैग इत्यादि को ध्यान में रखते हुएmysql अद्यतन

कभी-कभी यह शीर्षक और एच 1 टैग को डुप्लिकेट करता है, जब स्रोत में केवल एक ही होता है जब मैं इसे मैन्युअल रूप से देखता हूं।

कारण यह हो रहा है क्योंकि क्रॉल स्क्रिप्ट क्रॉन के माध्यम से चल रही है और ऐसा लगता है कि यह एक ही पृष्ठ को दो बार संसाधित करता है।

स्क्रिप्ट मूल रूप से एक पृष्ठ को पकड़ लेगा जिसे अनारक्षित किया गया है, तो यदि http प्रतिक्रिया 200 है तो यह इसे क्रॉल के रूप में चिह्नित करेगी, और इसकी आवश्यकता को संसाधित करेगी।

तो कहीं भी चयन और अद्यतन के बीच, स्क्रिप्ट का एक और धागा उसी पंक्ति पर चल रहा है जो चयनित था।

क्या एक ही क्वेरी में चयन और अद्यतन करने का कोई तरीका है, या चयन में लौटाई गई पंक्ति को लॉक करें ताकि इसे किसी अन्य प्रश्न में फिर से वापस नहीं किया जा सके जब तक कि मैं इसके साथ समाप्त नहीं हो जाता?

ने देखा है - http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html और अद्यतन सामग्री के लिए सामान्य चयन, लेकिन मैं अभी भी अनिश्चित हूं।

संपादित

मैं इस

START TRANSACTION; 
SELECT .. FOR UPDATE; 
UPDATE .... ; 
COMMIT; 

की तरह कुछ का उपयोग कर रहा लेकिन इसकी यह पसंद नहीं। मैं उस तालिका में InnoDB का उपयोग कर def def हूँ। मैं सोच रहा हूं कि यह आगे बढ़ने का तरीका नहीं हो सकता है, क्योंकि यह प्रतिबद्धता के बाद तक पंक्ति की प्रसंस्करण को रोकता है, जब मैं चाहता हूं कि यह शारीरिक रूप से फिर से पंक्ति को चुनने में सक्षम न हो।

मैंने इसे चयन करके कवर किया है, और उसके बाद इसे एक क्षेत्र को ध्वजांकित करने के लिए एक अद्यतन करने के बाद इसे संसाधित करने से पहले क्रॉल किया गया है, लेकिन तथ्य यह है कि यह निर्बाध नहीं है समस्या का कारण बन रहा है। मुझे निर्बाध रूप से फ़ील्ड को चुनने और अद्यतन करने का एक तरीका चाहिए, या जब तक मैं ऐसा नहीं कहता तब इसे फिर से चुना जा रहा है।

उत्तर

3

आप सवाल अपने आप :) जवाब दे दिया। SELECT FOR UPDATE बिल्कुल वही है जो आपको चाहिए यदि मैं आपका प्रश्न सही ढंग से समझूं। ऑटोोकॉमिट को बंद करना याद रखें, चुनने से पहले लेनदेन शुरू करें और अपडेट के बाद लेनदेन करें।

अद्यतन:

मुझे लगता है कि यह तुम क्या चाहते हो जाएगा:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 
BEGIN TRANSACTION; 
SELECT .. FOR UPDATE; 
UPDATE .... ; 
COMMIT TRANSACTION; 
+0

उदाहरण के किसी भी मौके पर रिकॉर्ड अपडेट करता है? मैंने ओपी को और जानकारी दी है लेकिन मुझे कोई भाग्य नहीं है – Horse

+0

इस्लामी लेवल सर्जिकल क्या करता है? मैंने इसे पढ़ा है (http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_serializable) लेकिन यह अधिक समझ में नहीं आता है। धन्यवाद! –

3

जब आप पंक्ति ताला (अद्यतन के लिए चयन के माध्यम से), अन्य लेनदेन ताला के लिए इंतजार करेंगे जारी होने की , पंक्ति को छोड़ने और अगले को चुनने के बजाय। बेहतर रणनीति तालिका में एक ध्वज कॉलम होगा (कोई भी, प्रसंस्करण, पूरा), शायद एक टाइमस्टैम्प के साथ। क्रॉन पंक्ति पकड़ता है, प्रसंस्करण के लिए ध्वज सेट करता है और पृष्ठ को संसाधित करना शुरू करता है। जब स्क्रिप्ट का एक और उदाहरण चल रहा है, तो वह पंक्तियों का चयन करता है जो 'प्रसंस्करण' स्थिति में नहीं हैं। जब क्रॉन खत्म होता है, तो यह एक बार फिर से 'पूर्ण'

+1

मैं मो में क्या कर रहा हूं, लेकिन फ्लैग को प्रसंस्करण में बदलने के लिए चयन और अद्यतन के बीच, इसे कभी-कभी ओवरलैपिंग थ्रेड में चयनित किया जा रहा है – Horse

+0

क्रॉन जॉब हर मिनट चलती है, लेकिन इसकी एक स्क्रिप्ट स्क्रिप्ट चल रही है 2 सेकंड अंतराल के साथ 30 बार स्क्रिप्ट – Horse

+0

अद्यतन के लिए चयन का उपयोग करें - विचार न्यूनतम समय के लिए ताला रखना है –

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