2017-07-07 57 views
0

我会尝试尽可能清楚我的问题。如果存在断开连接,MSSQL会提取连接

我使用这个特定的版本:https://github.com/patriksimek/node-mssql/tree/v3.3.0#multiple-connections mssql npm包。

我一直在寻找通过繁琐的(潜在的LIB)和微软文档的单证(见上面的链接GitHub的)

我无法找到任何东西,做一些简单的像getCurrentConnection,或getConnectionStatus或任何类似。

我有两种方法来解决这个问题,但我不满意他们两个,所以这就是为什么我在这里问。

我的第一种方法是设置一个超时并让connect函数在每个catch(err)上调用它自己。

第二个是在中间件中处理这个问题,但如果所有工作都正常,它将在每个请求上连接到SQL并再次关闭该连接。

我的中间件功能:

api.use(function(err, req, res, next){ 
    sql.close(); 
    sql.connect(config.database).then(() => { 
    next(); 
    }).catch(function(err) { 
    sql.close(); 
    server.main(); 
    }); 
}); 

PS所以要清楚,我想,如果可能的话拿起连接,而不是结束,并开始与问候一个新来当服务器或数据库崩溃,我仍然有一些来自兴奋功能的数据。

希望我清楚了。

回答

1

在Arnold的帮助下,我了解了mssql包,它的内部工作原理好得多。

为此,我想出了以下解决方案来解决我的问题。

let intervalFunction; 
const INTERVAL_DURATION = 4000; 

if (require.main === module){ 
    console.log("Listening on http://localhost:" + config.port + " ..."); 
    app.listen(config.port); 
    // try to connect to db and fire main on succes. 
    intervalFunction = setInterval(()=> getConnection(), INTERVAL_DURATION); 
} 

function getConnection() { 
    sql.close(); 
    sql.connect(config.database).then(() => { 
    sql.close(); 
    clearInterval(intervalFunction); 
    main(); 
}).catch(function(err) { 
    console.error(err); 
    console.log(`DB connection will be tried again in ${INTERVAL_DURATION}ms`) 
    sql.close(); 
    }); 
} 

一旦初始连接已建立,但它迷路了在此期间,池将自动拿起连接和处理您的连接

0

如果我正确理解你,你基本上想重用连接。繁琐内置了连接池,所以你不必担心重新使用它们:

var config = { 
    user: '...', 
    password: '...', 
    server: 'localhost', 
    database: '...', 
    pool: { 
     max: 10, 
     min: 0, 
     idleTimeoutMillis: 30000 
    } 
} 

在上述第(刚刚从您发布GitHub的URL复制)的例子中,将有10池中的连接可以使用。这就是美丽:池管理器将处理所有连接的使用和重用,也就是说,根据应用程序的需要,连接的数量是弹性的。

正如你所说,DB崩溃怎么样?这也是内置的:连接健康检查:

在内部,每个连接实例是TDS 连接的单独池。创建新的请求/事务/准备声明后,将从池中获取新的TDS连接,并保留 以执行所需的操作。一旦动作完成,连接被释放回池中的 。连接健康检查是内置的,所以一旦发现死亡连接 ,它立即被替换为 新的连接。

我希望这有助于!

+0

嗨阿诺德,感谢您的快速回复,这个事情你描述所有去了解你的关系。但在我的问题中,我指定有时我们的api在db之前启动。你会怎么做?我指定的方式,但不是在中间件功能?因此,不断重试catch(err)还是没有超时更清晰的方式? – Knopfler

+0

如果我使用这段代码: '代码' function getConnection(){ sql.close(); ()();> sql.connect(config.database).then(()=> { sql.close(); main(); console.log('werkt wel'); })。catch(function(err) ()=> { getConnection(),2000 }) });}};}}; } 'code' 而且我用docker打开sql server启动超时功能就会停止。一旦我重新启动节点进程,它就会工作,但我不想这样做。 – Knopfler

+0

对不起,对于迟到的回复,但国际海事组织你有两个选择来解决这个赛车条件(数据库没有准备好,当应用程序启动):1)未能启动应用程序。这就是我通常所做的。然后我在启动脚本中处理这个问题。在我的情况下,如果数据库没有准备好,根本就没有必要启动应用程序(!)。 2)让应用继续轮询数据库并继续直到数据库准备就绪。这也没关系,但是如果数据库永远不会准备好,那么在某个时候这需要失败。它看起来就是你在下面做的。 – arnold