سؤال

لقد قمت بإنشاء كود مثل هذا للحصول على الأخبار من تصدير XML من موقع ويب آخر وأحاول ملء قاعدة البيانات الخاصة بي به.

function UpdateLunchTime() {
    var httpRequest = require('request');
    var xml2js = require('xml2js');
    var parser = new xml2js.Parser();
    var url = 'http://www...com/export/xml/actualities';
    httpRequest.get({
            url: url
    }, function(err, response, body) {
        if (err) {
            console.warn(statusCodes.INTERNAL_SERVER_ERROR, 
                'Some problem.');
        } else if (response.statusCode !== 200) {
            console.warn(statusCodes.BAD_REQUEST, 
                'Another problem');
        } else {
            //console.log(body);
            parser.parseString(body, function (err2, result) {
                //console.log(result.Root.event);
                var count = 0;
                for (var i=0;i<result.Root.event.length;i++)
                { 
                    //console.log(result.Root.event[i]);
                    InsertActionToDatabase(result.Root.event[i]);
                }
                /*
                result.Root.event.forEach(function(entry) {
                    InsertActionToDatabase(entry);
                });
                */
            });
        }
    });
}

function InsertActionToDatabase(action)
{
    var queryString = "INSERT INTO Action (title, description, ...) VALUES (?, ?, ...)";
    mssql.query(queryString, [action.akce[0], action.description[0],...], {
    success: function(insertResults) {
    },
      error: function(err) {
      console.log("Problem: " + err);
      }
    });
}

بالنسبة للواقع الفردي، فهو يعمل بشكل جيد ولكن عندما أقوم بتشغيله على ملف XML بأكمله، أحصل على هذا الخطأ:

Error: [Microsoft][SQL Server Native Client 10.0][SQL Server]Resource ID : 1. The request limit for the database is 180 and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance.

وبالنسبة لبعض الكائنات الأخيرة، أحصل على هذا الخطأ:

Error: [Microsoft][SQL Server Native Client 10.0]TCP Provider: Only one usage of each socket address (protocol/network address/port) is normally permitted.

شكرا للمساعدة

هل كانت مفيدة؟

المحلول

تكمن المشكلة في أنك تحاول إجراء عدد كبير جدًا من العمليات (الإدراج) المتزامنة في قاعدة البيانات الخاصة بك.تذكر أن كل شيء في Node.js (تقريبًا) غير متزامن، لذلك عند الاتصال InsertActionToDatabase بالنسبة لأحد العناصر، ستبدأ هذه العملية على الفور ولن تنتظر حتى تنتهي للعودة.لذا فأنت تحاول بشكل أساسي إدراج كافة الأحداث مرة واحدة، وكما ذكرت رسالة الخطأ، هناك حد لعدد الاتصالات المتزامنة التي يمكن إجراؤها لخادم SQL.

ما عليك القيام به هو تغيير الحلقة الخاصة بك لتعمل بشكل غير متزامن، من خلال الانتظار حتى تكتمل إحدى العمليات قبل بدء العملية التالية (يمكنك أيضًا "دفعة" إرسال عدد أقل من العمليات في وقت واحد، والمتابعة بعد اكتمال كل دفعة ، لكن الكود أكثر تعقيدًا قليلاً) كما هو موضح أدناه.

var count = result.Root.event.length;
var insertAction = function(index) {
    if (index >= count) return;
    InsertActionToDatabase(result.Root.event[i], function() {
        insertAction(index + 1);
    });
}
insertAction(0);

و ال InsertActionToDatabase ستأخذ الدالة معلمة رد اتصال ليتم استدعاؤها عند الانتهاء.

function InsertActionToDatabase(item, done) {
    var table = tables.getTable('event');
    table.insert(item, {
        success: function() {
            console.log('Inserted event: ', item);
            done();
        }
    });
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top