mysql - Knex+MySQL UPDATE 然后 SELECT 有时会返回旧值
问题描述
以下代码有时会使用 Knex.js 从 MySQL 返回旧值:
await db.knex('table')
.where('id', '=', table_id)
.update({
last_opening: db.knex.fn.now(),
});
// ... removed another db.knex('table')...update() here for brevity, updating different fields
const updated_data = await db.knex('table')
.where('id', '=', table_id)
.select('last_opening')
.first();
// At this point updated_data.last_opening randomly contains either the old or the new date
db.knex
来自像这样的另一个模块:
// package.json has "knex": "^0.21.1",
const knex_factory = require('knex');
exports.knex = knex_factory({
client: 'mysql',
connection: {
host : conf.DB_HOST,
user : conf.DB_USER,
password : conf.DB_PASSWORD,
database : conf.DB_NAME,
}
});
它似乎只发生在生产环境中。根本无法在本地复制,并且不记得我是否在登台环境中看到过。
$ SELECT @@TX_ISOLATION;
REPEATABLE-READ
$ SELECT VERSION();
5.7.32-0ubuntu0.16.04.1
这个问题InnoDB / MySQL - new transaction using old data on SELECT 而不是返回更新的数据让我怀疑这与事务隔离级别和 Knex 的连接池有关,但我不了解足以轻松更改任何内容。
任何人都可以帮助解释发生了什么吗?
解决方案
我认为代码不应该/永远不会返回旧值,除非您同时多次运行该代码,例如,当 2 个请求处理程序可能一个接一个地更新该行,然后两者都从数据库中读取最后一个更新时。
此外,如果您有多个进程运行该代码,它也可能导致这种行为。
如果您将两个查询包装在一个事务中,即使更新同时运行也不应该发生。
推荐阅读
- gitignore - 作为开发人员,您是否使用 .gitignore 来忽略所有内容并故意包含?或者你只是排除它?
- ruby-on-rails - 在考试中显示问题的答案和响应
- sas - 在 SAS 中的美国地图上投影 AK、HI、PR
- python - 一年后为熊猫中的每个组创建具有值的列
- python - 如何为对数图创建每十年的点间距
- android - 如何在数组中包含的字符串中显示用户名
- javascript - 本地主机:3000 使用 React 时显示空白屏幕
- javascript - 循环遍历map函数
- programming-languages - 如何用dragon编程语言运行python程序文件
- django - 有什么方法可以将我的自定义用户模型中的多个用户(不同类型)关联到我的其他模型?