Nic*_*ick 5 javascript connection-pooling node.js express mysqljs
注意:此问题主要与节点中的单例对象有关,而不是与数据库池有关
我正在使用 mysqljs 节点模块进行数据库连接构建一个expressjs 应用程序。我想创建一个可以在整个应用程序中重用的单个池对象(对于不同的模型等)。我想知道在整个 Express 应用程序中使用单个对象实例的正确方法是什么
我见过很多例子,人们像这样创建 db.js 文件或 pool.js 文件,并在需要的地方需要它
// db.js
var mysql = require('mysql');
var pool;
module.exports = {
getPool: function () {
if (pool) return pool;
pool = mysql.createPool(dbConfig);
return pool;
}
};
// app.js
var pool = require('pool').getPool();
pool.query('SELECT * FROM users');
Run Code Online (Sandbox Code Playgroud)
但是我觉得这仍然不是正确的方法,因为您每次需要该对象时都依赖 Nodejs 缓存返回相同的实例。如果节点最终加载代码两次,您最终会得到两个池,例如
const poolA = require('./pool').getPool();
const poolB = require('./POOL').getPool(); // resolves to same file but node will not get result from cache
console.log(poolA === poolB); // false
Run Code Online (Sandbox Code Playgroud)
从我读过的大多数内容来看,由于这种行为,通常不建议在节点应用程序中使用单例对象,但这似乎是快速应用程序的常见用例。所以我想知道人们如何在应用程序的生命周期中创建他们的单一池?
注意:我目前正在做的是在应用程序根目录中实例化池,然后将该实例作为构造函数参数传递,但我也不喜欢这样做
简短回答
我没有看到你的代码有任何问题。
长答案
此解决方案假设您实际上没有使用POOL.js完全相同的代码命名的文件。
下面require解析为相同的文件,pool.js因为您使用的是启用的文件系统case-insensitivity。例如NTFS或APFS.
const poolB = require('./POOL').getPool();
Run Code Online (Sandbox Code Playgroud)
如果你case sensitive像这样使用文件系统,ext4你会得到错误。
Error: Cannot find module './POOL'
Run Code Online (Sandbox Code Playgroud)
node根据您提供的文件路径名在内部缓存文件。来自来源:
const relativeResolveCache = Object.create(null);
relResolveCacheIdentifier = `${parent.path}\x00${request}`;
const filename = relativeResolveCache[relResolveCacheIdentifier];
if (filename !== undefined)
...
Run Code Online (Sandbox Code Playgroud)
由于JavaScriptis case-sensitive,具有属性(简化)的对象(cache上面的 )将有所不同,并且引用完全不同的两个对象引用pool。POOL
结论
注意文件名或标识符名称的陷阱。
| 归档时间: |
|
| 查看次数: |
1816 次 |
| 最近记录: |