【问题标题】:Are all knex queries run in a transaction by default?默认情况下,所有 knex 查询都在事务中运行吗?
【发布时间】:2018-08-02 15:06:58
【问题描述】:

我没有使用knex.transactionknex.forUpdateknex.forShareknex.batchInsert 或任何显式创建事务的方法,但我的代码中出现了 DEADLOCK 错误。如果knex.js默认不创建事务,为什么要创建锁?

更新

当这些查询非常快速地执行两次时,我得到一个 DEADLOCK 异常。

let subquery2 = knex.select('pv2.*').from('projects_versions as pv2').innerJoin('versions_history as vh', 'pv2.version_id', 'vh.version_id').orderBy('vh.id', 'desc');
let subquery = knex.select('x.version_id').from(subquery2.as('x')).whereRaw('x.project_id = pv.project_id').limit(1);

let result = (await knex.raw('DELETE pv FROM projects_versions AS pv WHERE pv.version_id = ? AND NOT version_id = ?', [versionToDiscard, subquery]))[0];

if (!result.affectedRows) {
    await knex('projects_versions').update({ version_id: fifthVersion }).where('version_id', versionToDiscard);
}

【问题讨论】:

    标签: mysql transactions deadlock knex.js


    【解决方案1】:

    Knex 在运行迁移时默认创建隐式事务。否则 knex 不会创建任何隐式锁。

    问题中的信息太少,无法回答任何对此更有用的信息。

    【讨论】:

    • 我不是在谈论运行迁移。似乎 knex 确实 创建了隐式锁,因为我遇到了一些 DEADLOCK 错误。我只是找不到在哪里。例如,当我更新的问题中描述的查询非常快速地执行两次时,我得到了错误。可能是子查询强加锁的一种行为?
    • Knex 创建隐式锁。数据库可能会创建它们(knex 只是将查询发送到要执行的数据库,knex 不会发送任何额外的锁定查询)。无论如何,knex 确实使用多个连接来发送查询,因此您无法确定执行顺序,除非您在发送下一个查询之前等待先前查询的结果。
    猜你喜欢
    • 2014-10-02
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    相关资源
    最近更新 更多