Nodejs mysql откат транзакции не работает - PullRequest
0 голосов
/ 14 июля 2020

Я использую Nodejs MySQL и пытался создать транзакцию уровня базы данных, чтобы я мог выполнить кучу операторов в пакете и выполнить откат, если на каком-либо шаге есть ошибка. Я пытался следовать этому руководству.

Мой модуль базы данных:

let mysql = require('mysql')
let keys = require('../config/keys')
let util = require('util')

let pool = mysql.createPool({
    connectionLimit: 20,
    host: keys.connection.host,
    user: keys.connection.user,
    password: keys.connection.password,
    database: keys.connection.database,
    dateStrings: true
    // debug:true                //Set this to true for verbose debugging. Leaving this to default for now cause it is creating too many messages at my console
})
pool.getConnection((err, connection) => {
    if (err) {
        if (err.code === 'PROTOCOL_CONNECTION_LOST') {
            console.error('Database connection was closed.')
        }
        if (err.code === 'ER_CON_COUNT_ERROR') {
            console.error('Database has too many connections.')
        }
        if (err.code === 'ECONNREFUSED') {
            console.error('Database connection was refused.')
        }
    }
    if (connection) connection.release()
    return
})

pool.query = util.promisify(pool.query)

const connection = () => {
    return new Promise((resolve, reject) => {
        pool.getConnection((err, connection) => {
            if (err) reject(err);

            console.log("MySQL pool connected: threadId " + connection.threadId);

            const query = (sql, binding) => {
                return new Promise((resolve, reject) => {
                    connection.query(sql, binding, (err, result) => {
                        if (err) reject(err);
                        resolve(result);
                    });
                });
            };

            const release = () => {
                return new Promise((resolve, reject) => {
                    if (err) reject(err);
                    console.log("MySQL pool released: threadId " + connection.threadId);
                    resolve(connection.release());
                });
            };
            resolve({
                query,
                release
            });
        });
    });
};
// const query = (sql, binding) => {
//  return new Promise((resolve, reject) => {
//      pool.query(sql, binding, (err, result, fields) => {
//          if (err) reject(err);
//          resolve(result);
//      });
//  });
// };
module.exports = {
    pool,
    connection
}

В моем маршруте я пытаюсь использовать соединение, которое должно разрешить транзакцию:

const mysql = require('../../middleware/database')

async function buildCoreSchemas(){
      const connection = await mysql.connection();
    
    try{

        await connection.query("START TRANSACTION");

         await connection.query(`CREATE TABLE adjustreason (
            AdjustID int NOT NULL AUTO_INCREMENT,
            AdjustReason varchar(100) NOT NULL,
            PRIMARY KEY (AdjustID)
          )`)
      
        await connection.query(`insert into adjustreason(AdjustReason) values('sdsds')`) 
        
        await connection.query(`insert into adjustreason(FAKECOLUMN) values('sdsds')`)  
        await connection.query("COMMIT");
        }
    catch(err){
        await connection.query("ROLLBACK");
        console.log(err)
        return false
    }
    finally {
    await connection.release();
  }

Как видите, мой второй оператор вставки неверен, так как имя столбца FAKE COLUMN отсутствует. Итак, ошибка обнаруживается, и я получаю сообщение об ошибке в своей консоли:

Неизвестный столбец «FAKECOLUMN» в списке полей

Но когда я go и посмотрите на мою базу данных, транзакция не откатывается, потому что я вижу, что первая запись все еще там. Что я делаю не так?

1 Ответ

0 голосов
/ 14 июля 2020

Ciao, попробуйте изменить код следующим образом:

connection.beginTransaction(function(err) {
 if (err) { throw err; }
   connection.query(`CREATE TABLE adjustreason (
        AdjustID int NOT NULL AUTO_INCREMENT,
        AdjustReason varchar(100) NOT NULL,
        PRIMARY KEY (AdjustID)
      )`, function (error, results, fields) {
 if (error) {
  return connection.rollback(function() {
    throw error;
  });
 }

connection.query(`insert into adjustreason(AdjustReason) values('sdsds')`, function 
(error, results, fields) {
  if (error) {
    return connection.rollback(function() {
      throw error;
    });
  }

 connection.query(`insert into adjustreason(FAKECOLUMN) values('sdsds')`, function 
 (error, results, fields) {
  if (error) {
    return connection.rollback(function() {
      throw error;
    });
  }
  connection.commit(function(err) {
    if (err) {
      return connection.rollback(function() {
        throw err;
      });
    }
    console.log('success!');
  });
});
});
});
});

, чтобы вы вызывали connection.query внутри connection.beginTransaction, и если один из этих запросов завершился неудачно, вы вызываете connection.rollback. В противном случае connection.commit

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...