首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >node-mysql2:结果集未反映最新结果

node-mysql2:结果集未反映最新结果
EN

Stack Overflow用户
提问于 2020-02-27 19:58:24
回答 1查看 283关注 0票数 1

我正在使用node-mysql2,它有一个连接池,连接限制为10。当我重新启动应用程序时,结果很好-它们与我在数据库上的结果相匹配。但是,当我开始插入新记录并重做相同的select查询时,我得到的结果断断续续,遗漏了我刚刚添加的最新记录。

如果我直接检查数据库,我可以看到我刚刚通过我的应用程序添加的记录。只是应用程序不能以某种方式看到它。

我认为这是一个bug,但下面是我如何设置代码的:

代码语言:javascript
复制
module.exports.getDB = function (dbName) {
    if (!(dbName in dbs)) {
        console.log(`Initiating ${dbName}`);
        let config = dbConfigs[dbName];
        dbs[dbName] = mysql.createPool({
            host: config.host,
            port: config.port || 3306,
            user: config.user,
            password: config.password,
            connectionLimit: 10,
            database: config.database,
            debug: config.debug
        });
    }
    return dbs[dbName]; // I just initialize each database once
};

这是我的select查询:

代码语言:javascript
复制
let db = dbs.getDB('myDb');
const [rows] = await db.query(`my query`);
console.log(rows[0]); // this one starts to show my results inconsistently once I insert records

这是我的插入查询:

代码语言:javascript
复制
module.exports = {
    addNote: async function(action, note, userID, expID) {
        let db = dbs.getDB('myDb');

        await db.query(`INSERT INTO experiment_notes (experiment_id, action, created_by, note)
                            VALUES (?, ?, ?, ?)`, [expID, action, userID, note]);
    }
};

如果我将connectionLimit设置为1,我将无法重现问题...至少现在还不是

知道我做错了什么吗?

EN

回答 1

Stack Overflow用户

发布于 2020-03-02 20:46:42

connection_limit设置为1有一个有趣的副作用:它序列化从节点程序到数据库的所有访问。每个操作,无论是INSERT还是SELECT,都必须在下一个操作开始之前运行到完成,因为它必须等待池中的一个连接释放。

间歇性丢失行很可能是由于从池中的不同连接并发访问DBMS造成的。如果您从一个连接执行SELECT操作,而MySQL正在处理来自另一个连接的INSERT操作,那么SELECT并不总是能找到要插入的行。这是一个特性。它是ACID (atomicity, consistency, isolation, durability)的一部分。ACID对于DBMS的扩展至关重要。

在比您向我们展示的应用程序更复杂的应用程序中,当您使用DBMS事务并忘记提交它们时,同样的事情也会发生。

编辑多个数据库连接,即使是来自同一程序中同一池的连接,也是彼此独立工作的。因此,如果您在一个连接上执行尚未提交的事务,而在另一个连接上执行查询,则查询将(通常)反映事务开始之前的数据库状态。查询不能强制事务回滚,除非它以某种方式导致死锁。但是死锁会生成错误消息;您可能看不到任何错误消息。

有时,您可以通过使用SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;在同一连接上将查询放在前面来控制查询所看到的内容。在繁忙的DBMS上,这可以稍微提高查询性能,并防止一些死锁,只要您愿意让您的查询只看到事务的一部分。我用它来查询历史(昨天发生了什么)。它是文档化的here。默认值是SET TRANSACTION LEVEL REPEATABLE READ;,它解释了您所看到的内容

但是,避免这种隔离级别的东西,直到您需要它。(这条建议的标题是“太聪明是愚蠢的”。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60432745

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档