1

我正在尝试使用node-mssql从我的节点应用程序在远程 MS sql 服务器上执行存储过程。

问题:调用似乎是阻塞的,而不是异步的,因为除非第一个请求完成,否则从另一个客户端对应用程序的任何其他请求都不会得到响应。

 sql.connect(config).then(function() {
        new sql.Request()
        .input('mysp', sql.TVP, tvp)
        .execute('spParam1').then(function(recordsets) {
              callback(null, recordsets[0]);
        }).catch(function(err) {
            callback(err, []);
        });
    }).catch(function(err) {
         callback(err, []);
    });

提到的“回调”是 api 期望的函数回调。

我尝试了一个简单的例子

   setTimeout(function() {
                 callback("error.message", []);
   }, 60000);

在这种情况下,两个客户端都工作,Node 为第二个请求返回线程。

我已经尝试过使用承诺、回调和流式传输的示例。所有最终都会阻塞 I/O。

我在这里俯瞰什么?

编辑:只使用查询而不是“执行”,它按预期工作,没有阻塞 i/o

dbConn.connect().then(function () {
        logger.info("sql connection established")
        var request = new sql.Request(dbConn);
        // request.input('mysp', sql.TVP, tvp)
        //     .execute("spParam1").then(function (recordSet) {
            request.query("WAITFOR DELAY '00:00:22'").then(function(){
                dbConn.close();
                callback("no data", []);
            }).catch(function (err) {
                callback(err, []);
                logger.error(err)
                dbConn.close();
            });
    }).catch(function (err) {
        logger.error(err)
        callback(err, []);
    });
4

2 回答 2

0

这是我在没有任何阻塞的情况下进行的测试

SQL 过程

等待 1 分钟

CREATE PROCEDURE [dbo].[usp_node_test_wait]
AS
BEGIN
    SET NOCOUNT ON;

    WAITFOR DELAY '00:01:00';
    SELECT GETDATE() [date]
END

无需等待

CREATE PROCEDURE [dbo].[usp_node_test]
AS
BEGIN
    SET NOCOUNT ON;

    SELECT GETDATE() [date]
END

节点代码连接到数据库打开一个Web服务器

var sql = require('mssql');
var http = require('http');

var PORT = 8080 || process.env.PORT;


var config = {
    user: 'node',
    password: 'node',
    server: 'localhost',
    database: 'nodedb',
    options: {
        instanceName: 'sqlexpress'
    },
    pool: {
        max: 10,
        min: 0,
        idleTimeoutMillis: 30000
    },
    requestTimeout: 70000
}


var connection = new sql.Connection(config);


connection.connect(function(err){
    if(err){
        console.log('Error connecting to the DB ', err);
    } else {
        console.log('Database Connection Established');
        var server = http.createServer(handleRequest);
        server.listen(PORT, function(){
            console.log('Web server listening on http://localhost:%s', PORT);
        });

    }
});

function handleRequest(request, response){

    var req = request;
    console.log('Url Requested: ', req.url)
    if(req.url == '/nowait'){
        var request = new sql.Request(connection);
        request.execute('usp_node_test', function(err, recordsets, returnValue, affected){
            if (err) {
                console.log('Error: ', err)
            } else {
                var data = recordsets[0][0];
                console.log(data.date);
                response.end('Date returned by the server: ' + data.date);
            }

        });
    } else {
        var request = new sql.Request(connection);
        request.execute('usp_node_test_wait', function(err, recordsets, returnValue, affected){
            if (err) {
                console.log('Error: ', err)
            } else {
                var data = recordsets[0][0];
                console.log(data);
                response.end('Date returned by the server: ' + data.date);
            }
        });
    }

}

使用http://localhost/nowait让 sql 进程尽快在请求中使用http://localhost/anything挂起等待 1 分钟

您会看到一个请求不会干扰另一个请求,因此不会阻塞

于 2016-07-29T05:39:09.497 回答
0

刚刚从 Tedious 的人那里得到了确认 https://github.com/tediousjs/tedious/issues/475#issuecomment-260009906

看起来这是一个阻塞呼叫。

于 2016-11-16T21:17:23.537 回答