2010-05-05 14 views
7

हम एक बहु प्रक्रियाओं और बहु ​​थ्रेडेड अनुप्रयोग में SQLite का उपयोग कर रहे हैं। SQLite डेटाबेस फ़ाइलों को एम्बेडेड SQLite एन्क्रिप्शन का उपयोग करके एन्क्रिप्ट किया गया है। FAQ बताता है कि SQLite ताले तंत्र का उपयोग कर बहु ​​प्रक्रिया एक्सेस प्रबंधित करने में सक्षम होना चाहिए। हम एक अजीब समस्या का सामना कर रहे हैं: जब कई थ्रेड एक ही डेटाबेस फ़ाइल तक पहुंच रहे हैं, तो कभी-कभी उल्लंघनों का उल्लंघन होता है, अधिक विशेष रूप से - एक अद्वितीय बाधा वाले फ़ील्ड को "सम्मिलित या प्रतिस्थापित करें" कथन के बाद डुप्लिकेट मान मिल रहे हैं। यह अक्सर होता है, कि हम एन्क्रिप्शन का उपयोग कर रहे हैं। SQLite एन्क्रिप्शन का उपयोग शुरू करने से पहले हमने इस तरह के व्यवहार को नहीं देखा। क्या इसके साथ कोई विशिष्ट ज्ञात समस्या है?SQLite बहु प्रक्रिया का उपयोग

+0

SQLite बताता है कि आप समान ऑब्जेक्ट को थ्रेड में साझा नहीं कर सकते हैं। क्या आप वाकई ऐसा नहीं करते हैं? – Andrey

+0

@ एंड्री: क्या आप इस लिंक को पोस्ट कर सकते हैं? जब मैंने हाल ही में इसके बारे में पढ़ा है, तो SQLite का कहना है कि यह थ्रेड-सुरक्षित है, * हालांकि * उन्हें लगता है कि धागे बुरा हैं और आपको एक बहुप्रचारित प्रोग्राम में SQLite का उपयोग नहीं करना चाहिए, जब तक कि यह केवल एक थ्रेड तक पहुंच न हो। लेकिन तकनीकी रूप से, यह धागा सुरक्षित होना चाहिए। कम से कम, मुझे यही याद है। – Dave

+0

@ डेव: http://www.sqlite.org/cvstrac/wiki?p=Multi थ्रेडिंग कुंजी वाक्यांश: "थ्रेडसेफ" से हमारा मतलब है कि आप एक ही समय में विभिन्न थ्रेड में विभिन्न SQLite डेटाबेस कनेक्शन का उपयोग कर सकते हैं। – Andrey

उत्तर

8

जबकि SQLite कि "धागा सुरक्षित" आप अभी भी समवर्ती डेटाबेस को संशोधित नहीं कर सकते हैं:

प्रत्येक धागा तो रिकॉर्ड की एक संख्या डालने के लिए आगे बढ़ता है, चलो कहते हैं कि 1000 के समस्या आपके सामने आ जाएगा निम्न है: फ़ाइल को फ़ाइल पर लॉक सेट करके डेटाबेस पर नियंत्रण प्राप्त होगा। यह ठीक है, लेकिन बाकी थ्रेड के विफल होने पर विफल होने पर लॉक सक्रिय है। (reference)

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

आप ऐसा न करने-जबकि लॉक किया हुआ मुद्दा आप SQLITE_BUSY ध्वज की जांच कर सकते से बचना चाहते हैं: SQLITE_BUSY, जो मैं मूल रूप से ऐसा नहीं किया था के लिए

टेस्ट। यहाँ एक समाधान वर्णन करने के लिए कुछ छद्म कोड है:

while (continueTrying) { 
    retval = sqlite_exec(db, sqlQuery, callback, 0, &msg); 
    switch (retval) { 
     case SQLITE_BUSY: 
     Log("[%s] SQLITE_BUSY: sleeping fow a while...", threadName); 
     sleep a bit... (use something like sleep(), for example) 
     break; 
     case SQLITE_OK: 
     continueTrying = NO; // We're done 
     break; 
     default: 
     Log("[%s] Can't execute \"%s\": %s\n", threadName, sqlQuery, msg); 
     continueTrying = NO; 
     break; 
    } 
    } 

    return retval; 

same reference

मेरे शर्त अपने बाधा उल्लंघन multithreading के साथ कोई संबंध नहीं है, तो आपको लगता है कि आप वास्तविक बाधा उल्लंघन पोस्ट करें सकता है हो रहा है (या एक उदाहरण जो www.sscce.org का अनुपालन करता है)।

0

सुनिश्चित करें कि आप थ्रेड में कनेक्शन साझा नहीं कर रहे हैं - प्रत्येक थ्रेड को अपना कनेक्शन बनाना चाहिए। और सुनिश्चित करें कि आप लेनदेन में अपने प्रश्न लपेट रहे हैं।

मैं ओपन-सोर्स सिस्टम का उपयोग करता हूं। डेटा.क्लाइट (http://sqlite.phxsoftware.com/) ADO.Net wrapper, जो थ्रेड-सुरक्षित है जब तक आप धागे में कनेक्शन साझा नहीं करते हैं। यह यहां वर्णित डेटाबेस को आसानी से एन्क्रिप्ट करता है: http://sqlite.phxsoftware.com/forums/t/130.aspx (बस पासवर्ड प्रॉपर्टी सेट करें)। एन्क्रिप्शन करने के लिए और थ्रेड सुरक्षा के विवरण के लिए वह विशेष रूप से माइक्रोसॉफ्ट क्रिप्टो एपीआई का उपयोग कैसे करता है, इसके लिए अपने मंच को खोजें।

2

आपकी सभी टिप्पणियों के लिए धन्यवाद!

(यह उल्लेख करना है कि हम System.Data.SQLite का उपयोग कर रहे हैं।नेट पुस्तकालय)

इस बीच हम कुछ और परीक्षण किए गए और यहाँ परिणामों

===============

हम एक परीक्षक का निर्माण किया है हैं कि निम्न कार्य करता है: - कई फ़ील्ड वाली तालिका बनाएं। फ़ील्ड में से एक - nvarchar (255) - एक अद्वितीय इंडेक्स है: "तालिका (MyKey) पर अद्वितीय इंडेक्स IX_MyKey बनाएं" - कई निष्क्रिय प्रक्रियाओं (25) को एक साथ शुरू करें - प्रत्येक प्रक्रिया में एक कुंजी होती है (स्ट्रिंग एक संख्या 1-

रिकॉर्ड जहां MyKey = @ MyKey (प्रक्रिया की मुख्य) एक के एक मूल्य प्राप्त पढ़ें: - 25) प्रत्येक प्रक्रिया 30 सेकंड के लिए एक पाश में निम्न कार्य एक भी (मुख्य) धागा है संख्यात्मक क्षेत्र उसी रिकॉर्ड के उसी फ़ील्ड में 'मान + 1' वापस लिखें "डालें या प्रतिस्थापित करें ... जहां MyKey = @ MyKey"

===============

  • जब हम सब एन्क्रिप्शन के बिना System.Data.SQLite पुस्तकालय का उपयोग करके उपरोक्त करते हैं - सब कुछ उम्मीद के रूप में काम करता है (ताले कि धीमा कर रहे हैं सहित डेटाबेस जब प्रक्रियाओं की मात्रा बढ़ जाती है)

  • जब हम एन्क्रिप्शन (डेटाबेस के लिए एक पासवर्ड सेट) द्वारा उपयोग करते हैं, सूचकांक अद्वितीय विवश "टूटे" है के लिए उपयोग - वहाँ एक ही MyKey मूल्य

  • होने रिकॉर्ड दिखाई

===============

तो यह समस्या को किसी भी तरह से एन्क्रिप्शन से संबंधित है ...

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