2017-01-31 5 views
7

में 'db.serialize` काम कैसे करता है हाल ही में मैं sqlite3 में हेरफेर करने के लिए नोड और node-sqlite3 का उपयोग करना सीख रहा हूं, यहां एक नमूना है।`nb-sqlite3`

var sqlite3 = require('sqlite3'); 
var db = new sqlite3.Database(':memory:'); 
db.serialize(function() { 
    db.run("CREATE TABLE test(info TEXT)"); 
    db.run("INSERT INTO test (info) VALUES ('info1')"); 
}) 
db.close(); 

प्रलेखन कहा कि db.serialized सुनिश्चित करने के लिए एसक्यूएल लाइनों के क्रम में मार डाला गया इस्तेमाल किया गया था, लेकिन मैं उलझन में था, इसलिए वे db.serialize बिना क्रम में निष्पादित हो नहीं होता, सब के बाद वे घटना कतार से खींच लिया जाएगा और क्रम में निष्पादित? यह यहाँ कैसे काम करता है?

और यदि केवल एक वर्ग को निष्पादित किया जाना है, तो क्या यह db.serialize के बिना इसे चलाने के लिए सुरक्षित है?

var sqlite3 = require('sqlite3'); 
var db = new sqlite3.Database(':memory:'); 
db.run("CREATE TABLE test(info TEXT)"); 
db.close(); 
+0

कारणों में से एक: http://stackoverflow.com/ए/188 99872/1 9 3631 9 – Sizzler

उत्तर

8

serialize() समारोह के अंदर प्रत्येक आदेश समाप्त करने के लिए गारंटी है निष्पादित करने से पहले अगले एक शुरू होता है।

आपके उदाहरण में, CREATE TABLEINSERT से पहले समाप्त हो जाएगा। यदि आपने serialize() का उपयोग नहीं किया है तो CREATE TABLE और INSERT कथन समानांतर में चलाए जाएंगे। वे दूसरे के बाद इतनी जल्दी शुरू हो जाएंगे कि INSERT वास्तव में तालिका बनने से पहले समाप्त हो सकता है, जिससे आप उस तालिका में डेटा डालने का प्रयास करने में त्रुटि दे सकते हैं जो मौजूद नहीं है।

इसे दौड़ की स्थिति कहा जाता है, क्योंकि हर बार जब आप अपना प्रोग्राम चलाते हैं तो आपको एक अलग विजेता मिल सकता है। यदि CREATE TABLE दौड़ जीतता है तो कार्यक्रम ठीक काम करेगा। लेकिन अगर INSERT दौड़ जीतता है, तो प्रोग्राम एक त्रुटि के साथ टूट जाएगा। चूंकि आप दौड़ को जीतने वाले व्यक्ति को नियंत्रित नहीं कर सकते हैं, serialize()INSERT को CREATE TABLE तक शुरू होने से भी अंत तक पहुंच जाएगा, यह सुनिश्चित करने के लिए कि आप हर बार एक ही परिणाम प्राप्त करें।

आपके दूसरे उदाहरण में केवल एक कथन के साथ serialize() अभी भी आवश्यक है। ऐसा इसलिए है क्योंकि run() SQL क्वेरी प्रारंभ करता है लेकिन पृष्ठभूमि में चलाने के लिए क्वेरी को छोड़कर, तुरंत देता है। चूंकि आपका बहुत ही कमांड एक close() डेटाबेस है, इसलिए क्वेरी अभी भी चल रही है, तो आप इसे काट देंगे।

चूंकि serialize() तब तक वापस नहीं आता है जब तक कि इसके आंतरिक प्रश्नों को पूरा नहीं किया जाता है, इसका उपयोग करके क्वेरी को पूरा होने तक close() बंद कर दिया जाएगा।

यदि आप एक अलग प्रकार की क्वेरी का उपयोग कर रहे थे (किसी वेब पेज पर एक बटन पर क्लिक करने वाले उपयोगकर्ता के जवाब में कहें, जहां डेटाबेस कॉल के बीच खुला रहता है) तो आपको शायद serialize() की आवश्यकता नहीं होगी। यह केवल इस बात पर निर्भर करता है कि प्रत्येक क्वेरी का पालन करने वाले कोड की आवश्यकता है कि इससे पहले पूछे जाने वाले प्रश्न या नहीं।

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

(यह टिप close() तथापि पर लागू नहीं होता - अंगूठे का नियम वहाँ केवल close() कॉल करने के लिए एक बार सब कुछ चलना समाप्त कर दिया।)

शायद
+0

क्या यह गारंटी देने का कोई तरीका है कि कॉलबैक कॉल करने से पहले रन() कॉल खत्म हो जाएगा? मैं एक सेवपॉइंट के साथ सीरियलाइज का उपयोग कर रहा हूं, लेकिन अंततः कॉलबैक लौट रहा है लेकिन मेरे सीरियललाइज्ड प्रश्नों में से कोई भी अभी तक नहीं चला है और मैं अपने कोड को चलाने से पहले डेटाबेस पर बंद कर रहा हूं। यह एक बड़ी समस्या है क्योंकि मैं इन कॉलों से लौटाए गए डेटा का उपयोग करने की कोशिश कर रहा हूं। – Michael

+0

@ माइकल: यह सुनिश्चित न करें कि कॉलबैक होने पर 'रन()' का मतलब क्या है, लेकिन ऐसा लगता है कि यह एक टिप्पणी के बजाय एक नया प्रश्न होना चाहिए ताकि आप अधिक जानकारी प्रदान कर सकें। – Malvineous

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

  • कोई संबंधित समस्या नहीं^_^