2011-05-09 15 views
11

मैं एक्सप्रेस, और नोड-माइस्क्ल ड्राइवर का उपयोग करके node.js पर एक ऐप बना रहा हूं। मेरे ऐप में कुछ मामले हैं जब मुझे डेटाबेस प्रविष्टियों/अपडेट की एक श्रृंखला बनाने की आवश्यकता है। मैं उन्हें एक लेनदेन में चाहता हूं कि यदि दूसरा या तीसरा व्यक्ति विफल रहता है, तो पिछले आवेषण पूरी तरह से वापस लुढ़क जाते हैं।नोड.जेएस + माईएसक्यूएल - लेनदेन को संभालना

वर्तमान में, जिस तरह से मैं यह कर रहा हूं वह किसी प्रकार का मिडलवेयर है जो अनुरोध होने पर START TRANSACTION करता है। अनुरोध की प्रसंस्करण के दौरान, अगर कोई त्रुटि फेंक दी जाती है, तो मुझे यह त्रुटि मिलती है, और ROLLBACK करें। यदि कोई त्रुटि नहीं होती है, तो ब्राउज़र पर प्रतिक्रिया भेजने से पहले मैं COMMIT करता हूं।

हालांकि, अब मुझे चिंता है कि यह तब तक काम नहीं करेगा जब एकाधिक उपयोगकर्ता एक साथ एप्लिकेशन तक पहुंच सकें, क्योंकि MySQL एक मजबूर प्रतिबद्धता करता है यदि कोई अन्य अनुरोध START TRANSACTION के साथ अपना लेनदेन शुरू करने का प्रयास करता है! मैं वर्तमान में नोड के केवल एक उदाहरण का उपयोग कर रहा हूं, और सभी अनुरोधों के लिए एक एकल MySQL कनेक्शन का उपयोग कर रहा हूं।

क्या कोई मेरी सलाह दे सकता है कि मेरी चिंताओं वैध हैं, और लेनदेन के समर्थन में मुझे कैसे प्राप्त करना चाहिए?

+0

यदि आपके पास विकल्प है तो इसके बजाय सोफे/रेडिस/मोंगो का उपयोग करने के लिए उपयुक्त हो सकता है क्योंकि नोड के साथ अधिक आसानी से उपयोग किया जाता है। यदि आपके पास पहले से ही एक MYSQL डेटाबेस है जिसका उपयोग जारी है। – Raynos

+0

@ रेनोस AFAIK MongoDb के लेनदेन के लिए कोई समर्थन नहीं है ... – renatoargh

उत्तर

4

आपको क्लाइंट पूल बनाना होगा, या किसी अन्यथा यह सुनिश्चित करना होगा कि दो अलग-अलग पृष्ठ समान कनेक्शन पर कमांडर्स को कम नहीं कर रहे हैं (कम से कम उनमें से कोई भी लेनदेन में है)।

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

आप अपनी खुद की कतार बना और प्रबंधित कर सकते हैं, लेकिन यह सभी लेनदेन पृष्ठों को क्रमबद्ध करना समाप्त कर देगा (माना जाता है कि आप एकल कनेक्शन मॉडल के साथ चिपके हुए हैं)।

एक त्वरित googling से, ऐसा लगता है कि github पर कई नोड-mysql पूल हैं। उन्हें देखने के बाद, हालांकि, ऐसा नहीं लगता कि वे आपकी समस्या से मदद करेंगे।

1

मुझे यह विश्वास करना मुश्किल लगता है कि यदि कोई अलग सत्र START TRANSACTION निष्पादित करता है जो अन्य लेनदेन किए जाते हैं। यह पूरी तरह से असुरक्षित होगा, खासकर जब डेटा को रोलबैक करने की आवश्यकता होती है (या यह "वापस लुढ़का" है?)।

क्या यह संभव है कि आप इसे उसी सत्रSTART TRANSACTION के साथ मिश्रित कर रहे हैं?
http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html देखें जहां यह बताता है कि लेनदेन घोंसला नहीं जा सकता है। यह निश्चित रूप से उसी सत्र पर लागू होता है, किसी अन्य उपयोगकर्ता के सत्र में नहीं।

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

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

+0

MySQL के संदर्भ में, एक कनेक्शन एक 'सत्र' के बराबर है। ओपी एक कनेक्शन का उपयोग कर रहा है, इसलिए यह एक ही MySQL सत्र है जो सभी अनुरोध प्रसंस्करण में साझा किया जाता है। – SystemParadox

+0

@ सिस्टम पाराडॉक्स, यह सच है। मैं प्रश्न को अलग कनेक्शन के साथ एक समस्या समझ गया, और जब ओपी ने कहा "एकल कनेक्शन"/वह प्रति उपयोगकर्ता का मतलब था। – davin

6

चेक बाहर https://github.com/bminer/node-mysql-queues

मैं नोड mysql का समर्थन करने के लेन-देन और कई बयानों के लिए एक छोटे से आवरण को लागू किया। इसका परीक्षण नहीं किया गया है, और उत्पादन तैयार नहीं है ... लेकिन यह कुछ दिनों में होगा।:)

अद्यतन: मैंने इस पुस्तकालय का बहुत अच्छी तरह से परीक्षण किया है ... जाने के लिए अच्छा होना चाहिए!

5

कैसे जटिल अपने लेन-देन आप कुछ बदसूरत नेस्टिंग नोड से आपके प्रश्नों कतार की कोशिश कर रहा, बदसूरत चर scoping मुद्दों को पेश हो सकता है में आ सकते हैं पर निर्भर करता है।

क्या आप के बजाय कर सकते हैं एक संग्रहीत प्रक्रिया लिख ​​सकते हैं और SELECT द्वारा इसे समाप्त एक सफलता/असफलता झंडा ing, तो node-mysql जैसे आप कोई SELECT क्वेरी के साथ प्रक्रिया क्वेरी है। यहाँ संग्रहीत प्रक्रिया कैसे दिखाई दे सकती है:

DELIMITER // 
DROP PROCEDURE IF EXISTS MyProcedure // 
CREATE PROCEDURE MyProcedure(IN param1 VARCHAR/*, My, Parameters, ... */) 
BEGIN 

    DECLARE EXIT HANDLER FOR NOT FOUND, SQLWARNING, SQLEXCEPTION 
    BEGIN 
     ROLLBACK; 
     SELECT 0 AS res; 
    END; 

    START TRANSACTION; 
    # My Transaction ... 


    COMMIT; 
    SELECT 1 AS res; 

END // 
DELIMITER ; 

आपका नोड कोड कुछ इस तरह दिखेगा:

var mysql = require('mysql'); 

var client = mysql.createClient({ 
    host : '127.0.0.1', 
    user : 'username', 
    password: 'password' 
}); 
client.query('USE mydatabase'); 

var myParams = "'param1', 'param2', ... "; 
client.query("CALL MyProcedure(" + myParams + ")", function(err, results, fields) { 
    if (err || results[0].res === 0) { 
     throw new Error("My Error ... "); 
    } else { 
     // My Callback Stuff ... 

    } 
}); 
+0

यह वास्तव में समस्या से संपर्क करने का एक बहुत ही रोचक तरीका है - मैं सोच रहा हूं, शायद सर्वर-लॉन्च समय पर प्रीप्रोसेस प्रश्न और संग्रहित प्रक्रियाओं में ओआरएम को कॉल कन्वर्ट करें? मुझे आपके विचारों को काम करने के सर्वोत्तम तरीके से प्राप्त करना अच्छा लगेगा कि अगर आप मुझे एक नोट शूट करेंगे। मैं एक क्रॉस-डीबी ओआरएम पर काम कर रहा हूं जिसे वॉटरलाइन कहा जाता है। – mikermcneil

0

बस एक विचार: पर postresql आपका लेन-देन शुरू करने और इसे करने के लिए एक आईडी सेट कर सकते हैं। तो फिर, आप के आसपास ही कनेक्शन पुन: उपयोग, क्योंकि इस मामले में आप के लिए प्रतिबद्ध या रोलबैक करने की जरूरत है, तो आप, सही आईडी अपने लेन-देन का उल्लेख करने के लिए जा रहे हैं हो सकता है?

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