javascript – rollback doesn't work

Question:

So guys, I have a transaction to persist several data in different tables in my database, if by chance a record goes wrong I need it to rollback, after all I depend on the return of one's id to make the persistence of another one, moreover I can't let some tables be persisted and others not. The problem is that my rollback isn't working, I have some methods, they have a Promise so if there's an error, it rejects and in my view it would fall to the runQuery method's catch, then there's a rollback and this rollback to me it would undo the operations, the problem is that the errors are not falling there, and in this case the errors I am generating are several just for testing.

async run(data: any) {
try {
  const response = await this.runQuery(data);


  return 'response';
} catch (err) {
  throw err;
}}

async runQuery(data: any) {
try{
  connection.beginTransaction();  

  data[2].post.Ordem_servico = await this.insertGenericReturn(data[0]);

  await this.insertEpisOrder(data[6], data[2].post.Ordem_servico);

  data[5].post.Equipamento_FK = await this.insertGenericReturn(data[2]);

  data[3].post.Ordem_Servico = data[2].post.Ordem_servico;

  data[5].post.Locais_FK = await this.insertGenericReturn(data[3]);

  let listOperations : any = await this.insertOperationsOrder(data[4]);


  for (const element of listOperations) {
    data[5].post.Operacao_FK = element;
    await this.insertGenericReturn(data[5]);
  }

  connection.commit();

  return { result: 'Ordem de serviço criada!' }
} catch (err) {
  console.log('err runTransaction :>> ', err);

  await connection.rollback();
  throw err;
}}

private async insertGenericReturn(data: any) {
try {
  return new Promise((resolve, reject) => {
    connection.query(data.query, data.post,  async (err: any, result: any) =>{
      if (err) reject({ status: 401, msg: 'Não foi possível realizar a operação!', ...err })
      resolve(result.insertId);
    });
  });
} catch (err) {
  throw err;
}}

private async insertEpisOrder(data: any, order: any) {
try {
  return new Promise((resolve, reject) => {
    for (let index = 0; index < data.post.length; index++) {
      data.post[index].ordemServico_idOrdemServico = order;
    }
    for (const epi of data.post) {
      connection.query(data.query, epi, async (err: any, result: any) =>{
        if (err) reject({ status: 401, msg: 'Não foi possível realizar a operação!', ...err })
        resolve('EPIs cadastrados');
      });
    }
  });
} catch (err) {
  throw err;
}}

private async insertOperationsOrder(data: any) {
try {
  return new Promise((resolve, reject) => {
    let listOperations: any = [];
    let response: any;
    for (const item of data.post) {
      connection.query(data.query, item, async (err: any, result: any) =>{
        if (err) reject({ status: 401, msg: 'Não foi possível realizar a operação!', ...err })

        listOperations.push(result.insertId);

        resolve(listOperations);
      });
    }
  });
} catch (err) {
  throw err;
}}

Does anyone have any idea why I wouldn't be going to my rollback? type it goes to those insertion methods but I don't return to the runQuery catch that has the rollback, if you can help I appreciate it!

Answer:

Guys, I decided here and I'll share the resolution, maybe it's useful for someone:

I added a handle in catch the method is this

private getQueryError(err: any): { status: number, err: string } {
const error = Object.assign({}, err);

if (_.has(error, 'code')) return { status: 400, err: 'Não foi possível concluir a operação!' };
if (error.code === 'ER_DUP_ENTRY') return { status: 400, err: 'item já cadastrado!' };
return { status: 400, err: _.get(error, 'message', 'Não foi possível concluir a operação!') }}

And obviously I added calls to this method in my catch in this case:

const error = this.getQueryError(err);

Anyway, I hope it can help someone who is having this difficulty or who is working with transactions.

Scroll to Top