2012-06-15 10 views
9

मैं यह निर्धारित करने की कोशिश कर रहा हूं कि डेटाबेस में मेरा स्क्लाइट एक्सेस आईओएस पर थ्रेड-सुरक्षित है या नहीं। मैं एक गैर ऐप स्टोर ऐप (या संभवतः लॉन्च डिमन) लिख रहा हूं, इसलिए ऐप्पल की स्वीकृति कोई समस्या नहीं है। प्रश्न में डेटाबेस अंतर्निहित sms.db है, इसलिए यह सुनिश्चित करने के लिए कि ओएस भी इस डेटाबेस को पढ़ने और लिखने के लिए एक्सेस कर रहा है। मैं केवल इसे सुरक्षित रूप से पढ़ने में सक्षम होना चाहता हूं।इंटरप्रोसेस SQLite थ्रेड सुरक्षा (आईओएस पर)

मैं this about reading from multiple processes with sqlite पढ़ा है:

कई प्रक्रियाओं एक ही डाटाबेस एक ही समय में खुला हो सकता है। एकाधिक प्रक्रियाएं एक ही समय में एक चयन कर सकती हैं। लेकिन केवल एक प्रक्रिया समय में किसी भी समय डेटाबेस में परिवर्तन कर सकती है।

मैं समझता हूँ कि धागे की सुरक्षा SQLite से बाहर संकलित किया जा सकता है, और sqlite3_threadsafe() इस के लिए परीक्षण करने के लिए इस्तेमाल किया जा सकता है। आईओएस 5.0.1 पर इस रनिंग

int safe = sqlite3_threadsafe(); 

म्युटेक्स लॉकिंग का मतलब है कि 2. According to this का एक परिणाम, पैदावार उपलब्ध है। लेकिन, इसका मतलब यह नहीं है कि यह उपयोग में है।

मैं पूरी तरह से स्पष्ट नहीं हूं कि प्रति कनेक्शन, प्रति डेटाबेस, या वैश्विक आधार पर थ्रेड-सुरक्षा गतिशील रूप से सक्षम है या नहीं।

I have also read this। ऐसा लगता है कि सुरक्षित मल्टी-थ्रेडिंग सक्षम करने के लिए sqlite3_config() का उपयोग किया जा सकता है, लेकिन निश्चित रूप से, मेरे पास कोई नियंत्रण नहीं है, या दृश्यता है कि ओएस ने स्वयं इस कॉल का उपयोग कैसे किया हो (क्या मैं?)। अगर मैं अपने ऐप में फिर से कॉल करना चाहता था, तो क्या यह डेटाबेस को पढ़ने के लिए सुरक्षित बनाएगा, या यह मेरे ऐप में एकाधिक धागे के लिए समवर्ती पहुंच को केवल डीकॉनफ्लिक्ट करेगा जो उसी sqlite3 डेटाबेस हैंडल का उपयोग करता है?

वैसे भी, मेरे सवाल है ...

मैं सुरक्षित रूप से इस डेटाबेस भी आईओएस द्वारा पहुँचा है पढ़ सकते हैं, और यदि हां, तो कैसे?

उत्तर

10

मैंने कभी भी SQLite का उपयोग नहीं किया है, लेकिन मैंने अपने दस्तावेज़ों को पढ़ने में काफी समय बिताया है क्योंकि मैं भविष्य में इसका उपयोग करने की योजना बना रहा हूं (और दस्तावेज़ दिलचस्प हैं)। मैं कहूंगा कि थ्रेड सुरक्षा स्वतंत्र है कि एकाधिक प्रक्रियाएं एक ही डेटाबेस फ़ाइल को एक साथ एक्सेस कर सकती हैं या नहीं। SQLite, चाहे यह थ्रेडिंग मोड में है, lock the database file होगा, ताकि एकाधिक प्रक्रियाएं डेटाबेस से एक बार में पढ़ सकें लेकिन केवल कोई ही लिख सके।

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

संपादित करें: स्पष्ट करने के लिए, किसी भी समय आप डेटाबेस के लिए लिखते हैं, एक सादे INSERT/UPDATE/DELETE सहित, यह स्वतः ही एक विशेष ताला लगेगा, डेटाबेस के लिए लिखते हैं, तो अवरोध खोल। (और यह वास्तव में एक साझा लॉक लेता है, फिर एक सुरक्षित लॉक, फिर एक पेंडिंग लॉक, फिर लिखने से पहले एक विशेष लॉक।) डिफ़ॉल्ट रूप से, यदि डेटाबेस पहले ही लॉक हो गया है (किसी अन्य प्रक्रिया से कहें), तो SQLite प्रतीक्षा किए बिना SQLITE_BUSY वापस कर देगा । आप लंबे समय तक प्रतीक्षा करने के लिए कहने के लिए sqlite3_busy_timeout() पर कॉल कर सकते हैं।

+0

जब आप कहते हैं "* यह अभी भी कहना चाहिए, लिखने से पहले एक अनन्य ताला लें *", क्या आपका मतलब है कि SQLite स्वचालित रूप से ऐसा करेगा मुझे? या मैं (या आईओएस एसएमएस ढांचा) इसके लिए ज़िम्मेदार हूँ? उदाहरण के लिए, क्या मुझे (या आईओएस) लिखने से पहले 'BEGIN विशेष लेनदेन; 'कथन जारी करने की आवश्यकता है? – Nate

+0

मैंने एक संपादन जोड़ा। 'BEGIN विशिष्ट लेनदेन 'लेनदेन की शुरुआत में एक विशेष लॉक लेने के लिए है। डिफ़ॉल्ट रूप से, SQLite जितनी देर तक प्रतीक्षा कर सकता है। दस्तावेज़ों से: * ध्यान दें कि BEGIN आदेश डेटाबेस पर किसी भी ताले को प्राप्त नहीं करता है। BEGIN कमांड के बाद, जब पहला चयन कथन निष्पादित किया जाता है तो एक साझा लॉक प्राप्त किया जाएगा। एक सुरक्षित लॉक अधिग्रहित किया जाएगा जब पहला INSERT, अद्यतन, या DELETE कथन निष्पादित किया जाता है। * ... –

+0

... * कोई विशेष लॉक तब तक हासिल नहीं किया जाता है जब तक कि स्मृति कैश भर जाती है और उसे डिस्क पर या लेनदेन तक नहीं किया जाना चाहिए करता है। इस तरह, सिस्टम अंतिम फ़ाइल के लिए फ़ाइल फ़ाइल तक पढ़ने की पहुंच को अवरुद्ध करने में देरी करता है। * यदि आप 'BEGIN ट्रांज़ेक्शन' का उपयोग नहीं करते हैं, तो भी सभी कथन एक निहित लेनदेन में हैं। –

2

मैं इस के किसी भी नहीं लगता कि आप के लिए खबर है, लेकिन कुछ विचार:

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

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

जाहिर है, सबसे एक भी अनुप्रयोग के भीतर मल्टी-थ्रेडेड पहुँच के बारे में चिंतित उपयोगकर्ताओं के लिए, सबसे अच्छा वकील sqlite3_config() मूर्खता बायपास करने के लिए हो सकता है और बस अपने खुद के GCD धारावाहिक कतार के माध्यम से समन्वित पहुंच सुनिश्चित (यानी, के माध्यम से एक समर्पित कतार है जो सभी डेटाबेस इंटरैक्शन गुजरते हैं, मल्टी-थ्रेड इश्यू को पूरी तरह खत्म कर देते हैं)।अफसोस की बात है, यह यहां एक विकल्प नहीं है क्योंकि आप आईओएस के साथ डेटाबेस इंटरैक्शन को समन्वयित करने की कोशिश कर रहे हैं।

+0

आपकी विचारशील और अच्छी तरह लिखित प्रतिक्रिया के लिए धन्यवाद। सबसे पहले, शटडाउन के बारे में ... पूरे ओएस के लिए 'sqlite3_shutdown()' शट डाउन एसक्लाइट करता है, क्योंकि यदि ऐसा है, तो यह एक और इंटरप्रोसेस थ्रेड-सुरक्षा समस्या भी प्रतीत होता है। मुझे लगता है कि जब भी मैं .db पढ़ना चाहता हूं, तो एक असुरक्षित ऑपरेशन कुछ असुरक्षित करने से बेहतर हो सकता है, लेकिन शायद नहीं? – Nate

+0

और दूसरी बात, जीसीडी कतार मेरे स्वयं के कई धागे के बीच पहुंच को समन्वयित करने के लिए एक अच्छा तरीका प्रतीत होता है, लेकिन यह मेरी समस्या नहीं है (असल में, मेरा ऐप शायद एसक्यूएल ऑपरेशंस के लिए कभी भी अपने धागे का उपयोग करेगा)। मैं कतारों का उपयोग करने के लिए आईओएस को कैसे मजबूर कर सकता हूं? या क्या मुझे कुछ याद आ रहा है (आमतौर पर, जब मैं उस सवाल से पूछता हूं तो जवाब "हां" है!) – Nate

+0

@Nate अपने पहले प्रश्न के बारे में reqlite3_shutdown(), मैं इसका उत्तर नहीं दे सकता। मैं बस उन अन्य संदर्भों को उद्धृत कर रहा था। यह मुझे एक अच्छा विचार के रूप में नहीं रोकता है, लेकिन मैं नहीं कह सकता। – Rob

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