使用原始 SQL 表达式回滚 knex 事务

Rolling back knex transaction using raw SQL expressions

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

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 中有一个 wrongfield),我希望它不提交表达式的任何部分并回滚。相反,它执行前两个表达式(创建 table 和插入)。 知道出了什么问题吗?

与DDL(Data Definition Language)不能和DML(Data Manipulation Language)在交易中混用有关

DDL statements and operations with nontransactional engines do not "register" in thd->transaction lists, and thus do not modify the transaction state. Besides, each DDL statement in MySQL begins with an implicit normal transaction commit (a call to end_active_trans()), and thus leaves nothing to modify. However, as noted above for CREATE TABLE .. SELECT, some DDL statements can start a new transaction.

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