首页 > 解决方案 > 使用原始 SQL 表达式回滚 knex 事务

问题描述

我有一组要传递给 knex 的原始 SQL 表达式。

const rawExpressions = ["CREATE TABLE new_table (id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(30) NOT NULL,lastname VARCHAR(30) NOT NULL,email VARCHAR(50))","INSERT INTO new_table (firstname, lastname, email)VALUES (\"Test\", \"Name\", \"name@example.com\")", "INSERT INTO new_table (firstname, lastname, wrongfield) VALUES (\"Another\", \"Name\", \"test@example.com\")"]

knex.transaction(trx => {
  const queries: any[] = [];
  rawExpressions.forEach(async expression => {
    const query = knex.raw(expression).transacting(trx)
    queries.push(query)
  })

  Promise.all(queries)
    .then(trx.commit)
    .catch(trx.rollback)
}).catch(error => console.log('error', error))

如果没有错误,这有效,但如果有错误(在rawExpressions上面有 a wrongfield)我希望它不提交表达式的任何部分并回滚。相反,它执行前两个表达式(创建表和插入)。知道出了什么问题吗?

标签: mysqlknex.js

解决方案


这与DDL(Data Definition Language)在事务中不能与DML(Data Manipulation Language)混用有关。

带有非事务引擎的 DDL 语句和操作不会在 thd->transaction 列表中“注册”,因此不会修改事务状态。此外,MySQL 中的每个 DDL 语句都以隐式的正常事务提交(对 end_active_trans() 的调用)开始,因此没有任何可修改的内容。但是,正如上面对 CREATE TABLE .. SELECT 所述,一些 DDL 语句可以启动一个事务。

https://dev.mysql.com/doc/internals/en/transactions-notes-on-ddl-and-normal-transaction.html


推荐阅读