【问题标题】:What could cause mysql db read to return stale data什么可能导致 mysql db read 返回陈旧数据
【发布时间】:2021-07-26 03:24:35
【问题描述】:

我正在追查一个 mysql 应用程序的问题。在某些时候,我的客户使用包装在 START TRANSACTION; .... COMMIT; 语句中的查询插入了一些数据。紧接着另一个客户端来读回数据,但它不存在(我确定事情的顺序)。

我正在运行nodejs、express、mysql2,并使用连接池,有多个语句查询。

有趣的是,我在 mysqlworkbench 上看到了奇怪的东西。我只有一个工作台实例,它也看不到新插入的数据。我打开了第二个,它看到了新数据。几分钟后,第一个实例仍然看不到新数据。点击“重新连接到 DBMS”,现在它可以看到了。工作台行为,如果应用于我的节点客户端,将解释我在节点/mysql2 中看到的错误结果。

某处正在进行某种缓存...不知道从哪里开始 :-( 任何指针?谢谢!

【问题讨论】:

    标签: mysql node.js express mysql2


    【解决方案1】:

    听起来您的客户生活在他们自己的数据库快照中,如果他们有一个使用 REPEATABLE-READ 隔离级别的开放事务,那将是真的。换句话说,在该客户端开始其事务之后提交的任何数据都不会对该客户端可见。

    一种解决方法是强制启动新事务。只需在似乎正在查看陈旧数据的客户端会话中运行 COMMIT 即可。这将解决任何打开的事务,并且下一个查询将启动一个新事务。

    您可以测试的另一种方法是使用locking read query,例如SELECT ... FOR UPDATE。这将读取最近提交的数据,而不管客户端的事务隔离级别如何。也就是说,即使客户端使用 REPEATABLE-READ 开始了他们的事务,锁定读取的行为就像他们使用 READ-COMMITTED 开始他们的事务一样。

    【讨论】:

    • 果然,COMMIT 命令让新数据可见。当我最近转向池连接以提高性能时,这些问题开始出现。我想这毕竟不是一个透明的变化,需要注意!当您说“换句话说,在该客户端开始其事务后没有提交任何数据”时,您是指简单查询还是以 START TRANSACTION 语句开头的查询?
    • 我建议您阅读有关可重复读取快照的内容:dev.mysql.com/doc/refman/8.0/en/innodb-consistent-read.html
    猜你喜欢
    • 2020-06-23
    • 2023-03-04
    • 2019-01-24
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多