Проблема транзакции с knexjs, машинопись и mariadb - PullRequest
0 голосов
/ 14 января 2019

Я хочу иметь транзакцию в машинописном тексте для обновления некоторых данных в таблице Для этого необходимо выполнить следующие шаги:

  1. Усекать все записи из таблицы
  2. Установите AUTO_INCREMENT на 1
  3. Вставить новые записи в таблицу

Если что-то пойдет не так, я бы хотел откатить транзакцию и не изменять существующие записи в таблице БД.

Я пробовал разные вещи, но мне кажется, что я что-то упустил, и мне хотелось бы, чтобы кто-то заметил, что я делаю неправильно.

1-я попытка

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();
});

2-я попытка

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();
  }
});

3-я попытка

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);
}

Любая идея была бы действительно полезна.

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Не делай так. Вместо этого: * * 1001

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

Если произойдет сбой CREATE или populate, тогда отмените задачу; никто не пострадал. (Ну надо DROP TABLE real.)

RENAME TABLE очень быстрый, атомарный и вряд ли потерпит неудачу.

Этот подход имеет то преимущество, что для других запросов таблица real доступна и полностью заполнена за все время.

0 голосов
/ 14 января 2019

При использовании 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

...