2012-02-16 10 views
5

मुझे अपने पायथन/wsgi वेब ऐप में सत्रों में कोई समस्या है। 2 wsgi डिमन प्रक्रियाओं में से प्रत्येक में प्रत्येक थ्रेड के लिए एक अलग, लगातार mysqldb कनेक्शन है। कभी-कभी, पुराने सत्रों को हटाने और एक नया निर्माण करने के बाद, कुछ कनेक्शन अभी भी पुराने सत्रों को एक चयन में लाते हैं, जिसका अर्थ है कि वे सत्र को सत्यापित करने में विफल रहते हैं और फिर से लॉगिन करने के लिए कहते हैं।कुछ mysql कनेक्शन क्यों हटाए जाने के बाद mysql डेटाबेस पुराने डेटा का चयन कर रहे हैं?

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

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

मुझे कैश किए गए परिणाम क्यों मिल रहे हैं? कैशिंग कहाँ और हो सकती है, और इसे कैसे रोक सकता है या कैश रीफ्रेश कर सकता है? असल में, अन्य कनेक्शन नए डाले गए डेटा को देखने में विफल क्यों होते हैं?

उत्तर

9

MySQL अलगाव स्तर "दोहराया गया पढ़ने" के लिए डिफ़ॉल्ट है जिसका अर्थ है कि लेनदेन शुरू होने के बाद किए गए आपके लेनदेन में कोई भी परिवर्तन नहीं दिखाई देगा - भले ही उन (अन्य) परिवर्तन किए गए हों।

यदि आप उन सत्रों में कोई COMMIT या रोलबैक जारी करते हैं, तो आपको परिवर्तित डेटा देखना चाहिए (क्योंकि वह "प्रगति पर" लेनदेन को समाप्त कर देगा)।

दूसरा विकल्प उन सत्रों के लिए अलगाव स्तर को "प्रेषित पढ़ें" में बदलने के लिए है। शायद डिफ़ॉल्ट स्तर को बदलने का विकल्प भी है, लेकिन इसके लिए आपको मैन्युअल जांचना होगा।

+0

मैं सम्मिलित करने के बाद प्रतिबद्ध हूं (ऊपर संपादित)। क्या आपका मतलब है कि मुझे अन्य कनेक्शनों में भी प्रतिबद्ध या रोलबैक करना चाहिए? – jmilloy

+0

हां, आपको * अन्य * सत्र (या अलगाव स्तर को बदलने) के लेनदेन को समाप्त करने की आवश्यकता है –

+0

ग्रेट, मैंने प्रत्येक अनुरोध की शुरुआत में एक प्रतिबद्धता जोड़ा, और ऐसा लगता है कि ऐसा लगता है। हो सकता है कि अंत में ऐसा करना बेहतर हो, लेकिन किसी भी मामले में ... यदि मैं इसे एक या दो दिन तक रखता हूं तो मैं इसे सही के रूप में चिह्नित करने के लिए वापस आऊंगा। – jmilloy

2

हां, ऐसा लगता है कि धारणा यह है कि आप केवल एक ही लेनदेन करने जा रहे हैं और फिर डिस्कनेक्ट कर रहे हैं। यदि आपकी एक अलग आवश्यकता है, तो आपको इस धारणा के आसपास काम करने की आवश्यकता है। जैसा कि @a_horse_with_no_name द्वारा उल्लेखित किया गया है, आप एक प्रतिबद्धता डाल सकते हैं (हालांकि यदि आप वास्तव में डेटा नहीं बदल रहे हैं तो मैं रोलबैक का उपयोग करूंगा)।

dbcursor.execute("SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED")

या, आप स्वत: कनेक्शन पर सच के लिए प्रतिबद्ध सेट कर सकते हैं की तरह यह लग रहा है: - या आप कर्सर पर अलगाव के स्तर को बदल सकते हैं this discussion से मैं इस प्रयोग किया जाता

dbconn.autocommit(True)

हालांकि, फिर भी, वास्तव में कनेक्शन में परिवर्तन करने पर इसकी अनुशंसा नहीं की जाती है।

+1

मुझे 'db.autocommit (True) 'का उपयोग करना था, भले ही मैं सिर्फ' चयन 'कर रहा था और अंतर्निहित तालिकाओं को मेरी स्क्रिप्ट के बाहर बदल दिया गया था। – thedude

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