2012-05-30 3 views
5

मैं Node.js. का उपयोग कर एक साधारण सेवा पर काम कर रहा हूं। यह अपलोड की गई फाइलें प्राप्त करता है, उन्हें डिस्क पर संग्रहीत करता है और ओरेकल तालिका पर कुछ मेटाडेटा रिकॉर्ड करता है। मैं db-oracle पैकेज का उपयोग कर रहा कनेक्शन पूलिंग के साथ एक साथ, इस लेख निम्नलिखित: http://nodejsdb.org/2011/05/connection-pooling-node-db-with-generic-pool/डीबी-ओरैकल डेटा फ्लैश नहीं कर रहा है

हालांकि, मैंने देखा है कि डेटा मैं डालने केवल फोन करके Oracle डाटाबेस के लिए भेजा कनेक्शन पूल के बाद निष्क्रिय कनेक्शन बंद कर देता है है, इसकी disconnect() विधि।

क्या मेरे क्लाइंट को 'ओके' सिग्नल भेजने से पहले डेटा फ्लश करने का कोई तरीका है? जिस तरह से यह अब काम कर रहा है, मेरे webservice पर या ओरेकल पर एक क्रैश डेटा का नुकसान हो सकता है, और मेरी सेवा के ग्राहक को इसके बारे में पता नहीं चलेगा। कुछ अपलोड के बाद मैंने वास्तव में अपनी ऐप प्रक्रिया को मार कर इसका परीक्षण किया, और डेटा वास्तव में खो गया था।

यहाँ कोड का एक सरलीकृत संस्करण है:

var express = require('express'); 
var app = module.exports = express.createServer(); 

app.post('/upload', handleUpload); 

app.listen(4001, function(){ 
    console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env); 
}); 

function handleUpload(req, res) { 
    res.contentType('application/xml'); 

    var buf = ''; 
    req.on('data', function(chunk) { buf += chunk; }); 
    req.on('end', function() { 
    saveUpload(req, res, buf); 
    }); 
} 

function saveUpload(req, res, buf) { 
    if (buf.length == 0) 
    return sendError(res, 'No data supplied', 422); 

    var payload = new Buffer(buf, 'base64'); 

    files.save(payload, function(err, savedFile) { 
    if (err) 
     return sendError(res, 'Error while saving', 500); 

    var obj = { ip: req.connection.remoteAddress, location: savedFile.path, 
       created_at: new Date(), updated_at: new Date() }; 

    var fields = ['IP', 'LOCATION', 'CREATED_AT', 'UPDATED_AT']; 
    var values = fields.map(function(v) { return obj[v.toLowerCase()] }); 

    pool.acquire(function(err, conn) { 
     if (err) 
     return sendError(res, err, 500); 

     var q = conn.query().insert('FILES', fields, values); 

     q.execute(function(err, result) { 
     pool.release(conn); 

     if (err) 
      return sendError(res, err, 500); 

     if (result.affected < 1) 
      return sendError(res, 'Error saving the record', 500); 

     // The next statement sends the final result to the client. 
     // However, the new record was not yet flushed to the database. 
     res.end('<ok />'); 
     }); 
    }); 
    }); 
} 

function sendError(res, err, code) { 
    console.log(err); 
    res.send('<error>' + err + '</error>', code || 500); 
} 

समाधान के लिए, मैं एक नकली कनेक्शन पूल को लागू करने और सभी का अधिग्रहण कनेक्शन जारी करने के लिए कोशिश की है, लेकिन अब मेरे ऐप संदेश के साथ मर रहा है: pure virtual method calledAbort trap: 6

यहाँ नकली कनेक्शन पूलिंग है:

var fakePool = { 
    acquire: function(callback) { 
    new oracle.Database(config.database).connect(function(err, server) { 
     callback(err, this); 
    }); 
    }, 
    release: function(conn) { 
    conn.disconnect(); 
    } 
}; 

बस स्पष्ट होना, मैं नकली कनेक्शन Pooler के बारे में परवाह नहीं है, यह सिर्फ एक था गंदा कामकाज मैं अपने क्लाइंट को 'ओके' भेजकर से पहले ओरेकल पर डेटा फ्लश करने में सक्षम होना चाहता हूं।

Btw मैं भी उनके Github पर एक टिकट खोला: https://github.com/mariano/node-db-oracle/issues/38

+0

मैं किसी भी में प्रतिबद्ध नहीं दिख रहा है कोड ... –

+0

हाँ, 'डीबी-ओरैकल 'और' नोड-डीबी 'पैकेज किसी भी, AFAIK का पर्दाफाश नहीं करते हैं। मैंने अपने दस्तावेज और स्रोतों में पहुंचा दिया है और स्पष्ट रूप से प्रतिबद्धता करने का कोई तरीका नहीं मिला है। हालांकि, मैंने ओसीसीआई दस्तावेज़ों पर 'प्रतिबद्ध' विधि पाई है। शायद मुझे परियोजना को फोर्क करना होगा और प्रतिबद्ध विधि का पर्दाफाश करना होगा? –

+0

क्या ये पैकेज शायद (ugh!) ऑटो-प्रतिबद्ध व्यवहार पर निर्भर करते हैं? –

उत्तर

6

आप स्पष्ट रूप से एक लेनदेन प्रतिबद्धता खो रहे हैं।

नोड-डीबी को एक प्रतिबद्ध एपीआई का पर्दाफाश करने की आवश्यकता नहीं है क्योंकि अधिकांश आरडीबीएमएस (ओरेकल समेत) में, COMMIT एक मान्य क्वेरी है। चूंकि पैकेज मनमाने ढंग से प्रश्नों के निष्पादन के लिए अनुमति देता है, के लिए प्रतिबद्ध/रोलबैक एक सरल निष्पादित() का उपयोग किया जा करने वाले हैं

इस प्रकार कोड बदला जाना चाहिए:

pool.acquire(function(err, conn) { 
    if (err) 
    return sendError(res, err, 500); 

    var q = conn.query().insert('FILES', fields, values); 
    q.execute(function(err, result) { 

    if (err || result.affected < 1) { 
     pool.release(conn); 
     return sendError(res, err, 500); 
    } 

    conn.query().execute("commit", function(err,result) { 
     if (err) { 
     pool.release(conn); 
     return sendError(res, err, 500); 
     } 
     res.end('<ok />'); 
     pool.release(conn); 
    }); 
    }); 
}); 
+0

मैं इसे आज़मा दूंगा, धन्यवाद! –

1

यह आपके प्रश्न का सटीक उत्तर नहीं है, लेकिन node-oracle पैकेज पर एक नजर है। इसमें कनेक्शन पूलिंग की कमी है, लेकिन इसकी commit/rollback कार्यक्षमता कम से कम कोड से नियंत्रित की जा सकती है। और आप इसे हमेशा generic pool solution such as node-pool के साथ मिश्रित कर सकते हैं।

+0

धन्यवाद, @ एनपी ... मैं 'नोड-ऑरैकल' भी कोशिश करूंगा। दुखद बात यह है कि यह 'नोड-डीबी' के साथ एकीकृत नहीं है। –

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