【问题标题】:Transaction issue with knexjs, typescript and mariadbknexjs、typescript 和 mariadb 的事务问题
【发布时间】:2019-01-14 10:27:42
【问题描述】:

我想在打字稿中进行事务以刷新表中的一些数据。为此,需要执行以下步骤:

  1. 截断表中的所有记录
  2. 将 AUTO_INCREMENT 设置为 1
  3. 在表中插入新记录

如果出现问题,我想回滚事务并且不更改 db 表中的现有记录。

我尝试了不同的方法,但我认为我遗漏了一些东西,我希望有人能发现我做错了什么。

第一次尝试

await knex.transaction(async (trx) => {
  await knex(tableName).truncate().transacting(trx);
  await knex.raw(`ALTER TABLE ${tableName} AUTO_INCREMENT=1;`).transacting(trx);
  await knex(tableName).insert(data).transacting(trx);
  await trx.commit();
});

第二次尝试

await knex.transaction(async (trx) => {
  try {
    await knex(table).truncate().transacting(trx);
    await knex.raw(`ALTER TABLE ${table} AUTO_INCREMENT=1;`).transacting(trx);
    await knex(table).insert(data).transacting(trx);
    await trx.commit();
  } catch (e) {
    await trx.rollback();
  }
});

第三次尝试

const promisify = (fn: any) => new Promise((resolve, reject) => fn(resolve));
const trx: knex.Transaction  = <knex.Transaction> await promisify(this.knex.transaction);
try {
  await this.knex(this.table).truncate().transacting(trx);
  await this.knex.raw(`ALTER TABLE ${this.table} AUTO_INCREMENT=1;`).transacting(trx);
  await this.knex(this.table).insert(data).transacting(trx);
  await trx.commit();
  return Promise.resolve(data);
} catch (e) {
  await trx.rollback();
  return Promise.reject(e);
}

任何想法都会非常有用。

【问题讨论】:

  • 感谢您撰写本文;我有完全相同的问题。下面的两个答案都有帮助

标签: typescript mariadb knex.js


【解决方案1】:

使用 mysql,所有改变模式的 DDL 查询都会隐式提交,并且不能回滚。所以你需要改变你的实现,以其他方式保证数据库的完整性。

https://dev.mysql.com/doc/refman/8.0/en/cannot-roll-back.html https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html

【讨论】:

    【解决方案2】:

    不要那样做。而是:

    CREATE TABLE new LIKE real;
    populate `new`
    RENAME TABLE real TO old, new TO real;
    DROP TABLE old;
    

    如果CREATEpopulate失败,则放弃任务;没有造成伤害。 (嗯,需要DROP TABLE real。)

    RENAME TABLE 非常快,而且是原子的,不太可能失败。

    这种方法的优势在于,对于其他查询,real 表始终可用并完全填充。

    【讨论】:

    • 不错的技巧,指向原始表的外键引用会发生什么?我想必须以指向新表的方式删除/重新创建它们?
    • @MikaelLepistö - 啊,是的,我避免使用 FK 的另一个原因。尝试在操作期间禁用 FK。
    猜你喜欢
    • 1970-01-01
    • 2017-11-26
    • 1970-01-01
    • 2021-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    相关资源
    最近更新 更多