Node.js mssql 到 SQL 服务器的多个并发连接相互干扰

安皮格

在 Node.js express 应用程序中使用mssql跨许多不同的 SQL 服务器连接到许多不同的数据库。

我构建了以下示例来演示我的代码的一般结构:

app.get('/api/example'), async (request, response) => {

    // FYI I may be using await incorrect here since I'm new to it, just using it here for code simplicity
    let results1 = await GetDataFromSqlServerA()
    let results2 = await GetDataFromSqlServerB()

    response.status(200).send([results1, results2])
});

function GetDataFromSqlServerA() {
    return new Promise(function(resolve, reject)    {

        let sql = require("mssql")

        let sqlConnectionDetails = {
            user: 'test',
            password: 'foobar',
            server: 'SQLServerA', 
            database: 'DatabaseA'
        }

        sql.connect(sqlConnectionDetails, function (error)    {

            let sqlRequest = new sql.Request()
            let queryText = 'SELECT * FROM TableA'

            sqlRequest.query(queryText, function (error, results) {
                sql.close()
                resolve(results)
            })
        })
    })
}

function GetDataFromSqlServerB() {
        return new Promise(function(resolve, reject)    {

        let sql = require("mssql")

        let sqlConnectionDetails = {
            user: 'test',
            password: 'foobar',
            server: 'SQLServerB', 
            database: 'DatabaseB'
        }

        sql.connect(sqlConnectionDetails, function (error)    {

            let sqlRequest = new sql.Request()
            let queryText = 'SELECT * FROM TableB'

            sqlRequest.query(queryText, function (error, results) {
                sql.close()
                resolve(results)
            })
        })
    })
}

我有一个请求,它从两个单独的 SQL 服务器位置异步查找数据。要进行的第一个 SQL 调用执行正常,但第二个失败Invalid object 'Table2'它无法找到该表,因为出于某种原因,第二个调用获取了第一个调用的连接详细信息。它指向错误的 SQL 服务器和数据库!

我会认为这是不可能的,因为这些功能在它们自己的范围内。第一个 SQL 调用应该对第二个 SQL 调用一无所知,反之亦然 - 或者至少我会这么想。

我也尝试过在全局定义一个sql实例,但发生了同样的问题。

我可以有一个函数与服务器 A 建立 SQL 连接,向服务器 A 发出请求,断开与服务器 A 的连接,建立与服务器 B 的 SQL 连接,最后向服务器 B 发出请求。但是,当异步性开始发挥作用时并且 SQL 是由并发请求触发的,我有问题。

希望我只是愚蠢,因为我是异步代码的新手,请赐教!谢谢!

安皮格

我想我会更新这个以防其他人遇到类似的问题。@AlwaysLearning 为我提供了一个链接,指向 mssql npm 文档的一部分,该文档解释了连接池,并在需要访问多个数据库时这样做。我建议通读一遍

原来mssql的.connect()函数是全局的。如果调用 .connect() 函数时全局池已经连接,它将解析为已经连接的池。这给我带来了麻烦,因为当快速连续发送两个请求时,我的应用程序中会发生以下情况:

  1. 请求 1 将连接到数据库 A
  2. 请求 2 将尝试连接到数据库 B
  3. 由于数据库 A 已经在全局池中连接,请求 2 拿起数据库 A 连接
  4. 请求 2 的 SQL 查询失败,因为它对数据库 A 无效

为了解决这个问题,您需要开发一些连接池管理代码。通过这种方式,您可以确保每个必需的数据库连接都有单独的连接池。此外,这是一种加快查询速度的简单方法,因为您不需要每次发出请求时都重新连接到数据库。

npm 文档提供了几个示例帮助文件,但我发现它们对我来说并不理想,而且我无法在我的环境中编译所有代码。我将代码自定义为以下内容:

mssql-connection-pooling.js:

const { ConnectionPool } = require('mssql')
const pools = {}
 
// create a new connection pool
function CreatePool(config) {
    let key = JSON.stringify(config)

    if (GetPool(key))
        throw new Error('Pool already exists')

    pools[key] = (new ConnectionPool(config)).connect()
    return pools[key]
}

// get a connection pool from all pools
function GetPool(name) {
  if (pools[name])
    return pools[name]
  else
    return null
}

// if pool already exists, return it, otherwise create it
function GetCreateIfNotExistPool(config)  {
    let key = JSON.stringify(config)

    let pool = GetPool(key)
    if(pool)
        return pool
    else
        return CreatePool(config)
}

// close a single pool
function ClosePool(config) {
    let key = JSON.stringify(config)

    if (pools[key]) {
        const pool = pools[key];
        delete pools[key];
        pool.close()
        return true
    }
    return false
}

// close all the pools
function CloseAllPools() {
    pools.forEach((pool) => {
        pool.close()
    })
    pools = {}
    return true
}
 
module.exports = {
  ClosePool,
  CloseAllPools,
  CreatePool,
  GetPool,
  GetCreateIfNotExistPool
}

我创建了 GetCreateIfNotExistPool() 函数,您提供了一个数据库连接配置对象。该函数检查池中是否为给定的连接配置存储了一个打开的连接。如果有,它只返回连接池。如果没有,它会创建它然后返回它。

用法示例:

const sql = require("mssql");
let mssql = require('./mssql-pool-management.js')

let exampleDBConfigA = {
    user: 'test',
    password: 'password,
    server: 'SqlServerA', 
    database: 'DatabaseA'
};
let exampleDBConfigB = {
    user: 'test',
    password: 'password,
    server: 'SqlServerB', 
    database: 'DatabaseB'
};

...

// Request 1
try {
    let sqlPool = await mssql.GetCreateIfNotExistPool(exampleDBConfigA)
    let request = new sql.Request(sqlPool)

    // query code
}
catch(error) {
    //error handling
}

...

// Request 2
try {
    let sqlPool = await mssql.GetCreateIfNotExistPool(exampleDBConfigB)
    let request = new sql.Request(sqlPool)

    // query code
}
catch(error) {
    //error handling
}

在这个例子中,请求 1 和 2 可以同时调用,它们的连接不会干扰!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

通过 MSSQL Node.js 从 SQL 读取数据

Angular页面到Node.js服务器套接字的连接

ngFlow到Forimidable node.js服务器

使用Node.js MSSQL连接时的输出问题

RequestError:连接丢失-在Node.js中读取mssql的ECONNRESET

Node JS mssql 导出数据库连接

Node.js - 从多个 MSSQL 查询返回数据

Visual Studio Code mssql扩展:SQL Server(mssql)-无法连接到服务器

具有多个并发请求的Node.js服务器,它如何工作?

我如何检查从 angular 到 node.js 传递到服务器的数据

Azure ADAL-如何获取刷新令牌/如何刷新Node.js后端服务器到服务器连接的访问令牌?

node.js http服务器并发问题

从 React.js 组件到 Node.js 服务器的 POST 请求问题

请求正文未从 Next.js 传递到 Node.js 服务器

将JSON数据从iOS发布到mssql服务器

Node.js mssql模块非常慢

从一个Node.js服务器到同一服务器中另一Node.js服务器的调用函数

将数据从路由器传递到服务器文件 node.js express

如何将jwt从swift客户端传递到node.js服务器

如何在Ajax调用中将函数从JQuery传递到Node.JS服务器

将套接字服务器从Node.js移植到C#

HTML到Node.js中的PNG服务器端

如何正确地将图像发布到alchemy node.js服务器?

将War部署到远程Node.js服务器

代表用户通过Node.js服务器发布到YouTube

Node.js MSSQL tedius ConnectionError:无法连接到本地主机:1433-连接ECONNREFUSED

使用“ node-mssql” npm包添加多个输入以查询MS SQL Server实例

Node.js-使用MSSQL包动态添加多个参数

在泊坞连接SQL服务器到Python