2

I have a problem. In my NodeJS code, I have executed queries successfully, but now I am trying to work with transactions, but I get an error. Here is the code:

db.js:

require('dotenv').config({ path: 'src/api/v1/.env' });
const mysql = require('mysql2');

const pool = mysql.createPool({
    connectionLimit: 10,
    host: process.env.DB_HOST,
    user: process.env.DB_USER,
    database: process.env.DB_NAME,
    password: process.env.DB_PASSWORD,
})

module.exports = pool.promise();

transaction.js

const db = require('../../config/db');

function updateDatabaseOrderExecution(order, marketWallet, coinWallet) {
    return new Promise((resolve, reject) => {
        db.getConnection().then((err, connection) => {
            console.log(err)
            if (err) {
                return reject("Error occurred while getting the connection");
            }
            connection.beginTransaction(err => {
                if (err) {
                    connection.release();
                    return reject("Error occurred while creating the transaction");
                }
                return connection.query(
                    Wallet.getSaveQuery(), [Wallet.objectToArray(marketWallet)], (err) => {
                        if (err) {
                            connection.rollback(() => {
                                connection.release();
                                return reject("Failed updating market wallet", err)
                            });
                        }
                        connection.query(
                            Wallet.getSaveQuery(), [Wallet.objectToArray(coinWallet)], (err) => {
                                if (err) {
                                    connection.rollback(() => {
                                        connection.release();
                                        return reject("Failed updating coinWallet");
                                    });
                                }
                                connection.query(
                                    Order.getSaveQuery(), [Order.objectToArray(order)], (err) => {
                                        if (err) {
                                            connection.rollback(() => {
                                                connection.release();
                                                return reject("Failed inserting order");
                                            });
                                        }
                                        connection.commit((err) => {
                                            if (err) {
                                                connection.rollback(() => {
                                                    connection.release();
                                                    return reject("Commit failed");
                                                });
                                            }
                                            connection.release();
                                            return resolve({ message: "Order is executed", order})
                                        });
                                    })

                            });
                            })

                    });

            });
        });
}

When I call this function, the code crashes on the first error of db.getConnection():

PromisePoolConnection {
  _events: [Object: null prototype] {
    newListener: [Function (anonymous)],
    removeListener: [Function (anonymous)]
  },
  _eventsCount: 2,
  _maxListeners: undefined,
  connection: PoolConnection {
    _events: [Object: null prototype] { end: [Function], error: [Array] },
    _eventsCount: 2,
    _maxListeners: undefined,
    config: ConnectionConfig {
      isServer: undefined,
      stream: undefined,
      host: 'localhost',
      port: 3306,
      localAddress: undefined,
      socketPath: undefined,
      user: 'alexander',
      password: 'abcdefghijk',
      passwordSha1: undefined,
      database: 'personal',
      connectTimeout: 10000,
      insecureAuth: false,
      supportBigNumbers: false,
      bigNumberStrings: false,
      decimalNumbers: false,
      dateStrings: false,
      debug: undefined,
      trace: true,
      stringifyObjects: false,
      enableKeepAlive: false,
      keepAliveInitialDelay: 0,
      timezone: 'local',
      queryFormat: undefined,
      pool: [Pool],
      ssl: false,
      multipleStatements: false,
      rowsAsArray: false,
      namedPlaceholders: false,
      nestTables: undefined,
      typeCast: true,
      maxPacketSize: 0,
      charsetNumber: 224,
      compress: false,
      authPlugins: undefined,
      authSwitchHandler: undefined,
      clientFlags: 11203535,
      connectAttributes: undefined,
      maxPreparedStatements: 16000
    },
    stream: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'tohatsu.lava',
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 4,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: null,
      _server: null,
      [Symbol(async_id_symbol)]: 7,
      [Symbol(kHandle)]: [TCP],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0
    },
    _internalId: 0,
    _commands: Denque {
      _head: 1,
      _tail: 1,
      _capacity: undefined,
      _capacityMask: 3,
      _list: [Array]
    },
    _command: undefined,
    _paused: false,
    _paused_packets: Denque {
      _head: 0,
      _tail: 0,
      _capacity: undefined,
      _capacityMask: 3,
      _list: [Array]
    },
    _statements: LRUCache {
      [Symbol(max)]: 16000,
      [Symbol(lengthCalculator)]: [Function: naiveLength],
      [Symbol(allowStale)]: false,
      [Symbol(maxAge)]: 0,
      [Symbol(dispose)]: [Function: dispose],
      [Symbol(noDisposeOnSet)]: false,
      [Symbol(updateAgeOnGet)]: false,
      [Symbol(cache)]: Map(0) {},
      [Symbol(lruList)]: [Yallist],
      [Symbol(length)]: 0
    },
    serverCapabilityFlags: 2176841726,
    authorized: true,
    sequenceId: 14,
    compressedSequenceId: 0,
    threadId: 663,
    _handshakePacket: Handshake {
      protocolVersion: 10,
      serverVersion: '5.5.5-10.3.34-MariaDB-0ubuntu0.20.04.1-log',
      capabilityFlags: 2176841726,
      connectionId: 663,
      authPluginData1: <Buffer 51 27 6c 6c 5b 60 52 5b>,
      authPluginData2: <Buffer 50 60 71 39 65 74 35 4a 55 4d 61 23 00>,
      characterSet: 8,
      statusFlags: 2,
      autPluginName: 'mysql_native_password'
    },
    _fatalError: null,
    _protocolError: null,
    _outOfOrderPackets: [],
    clientEncoding: 'utf8',
    packetParser: PacketParser {
      buffer: [],
      bufferLength: 0,
      packetHeaderLength: 4,
      headerLen: 0,
      length: 5,
      largePacketParts: [],
      firstPacketSequenceId: 0,
      onPacket: [Function (anonymous)],
      execute: [Function: executeStart],
      _flushLargePacket: [Function: _flushLargePacket4]
    },
    serverEncoding: 'latin1',
    connectTimeout: null,
    _pool: Pool {
      _events: [Object: null prototype] {},
      _eventsCount: 0,
      _maxListeners: undefined,
      config: [PoolConfig],
      _allConnections: [Denque],
      _freeConnections: [Denque],
      _connectionQueue: [Denque],
      _closed: false,
      [Symbol(kCapture)]: false
    },
    connectionId: 663,
    [Symbol(kCapture)]: false
  },
  Promise: [Function: Promise],
  [Symbol(kCapture)]: false
}

The credentials are correct, because I can execute other queries successfully. I got the code from: https://stackoverflow.com/a/45285300/10673107. The only difference is that he uses mysql and I use mysql2, but in both versions the getConnection() function exists... What am I doing wrong?

A. Vreeswijk
  • 822
  • 1
  • 19
  • 57
  • 3
    If you ask for help with an error, it is customary to share the exact error message you got in your log. Help us to help you! Don't make us guess at the error. – Bill Karwin Apr 04 '22 at 22:31
  • You have a line `console.log(err)`. Should I assume from this that there is some output in your console log? – Bill Karwin Apr 04 '22 at 22:33
  • Okay I will back off, because I am not an expert with Node.js. But I notice your callback for getConnection() logs the "err" before it checks if there is actually an error. Is that correct? – Bill Karwin Apr 04 '22 at 22:47
  • I call the method `getConnection()`. In this callback I get an `err` and a `connection`. Then I check if the error variable has been filled. In my case it is, so `connection` is `undefined`. So I check for an error and then quit the entire function, but I have no idea why the error occurs – A. Vreeswijk Apr 04 '22 at 22:53
  • 2
    You should _really_ rewrite this to async/await. I wrote some docs on what good transaction code looks like with mysql2. These nested promises are so hard to read: https://evertpot.com/executing-a-mysql-query-in-nodejs/ – Evert Apr 07 '22 at 01:08
  • 1
    Tessa, writing it like your way helped me fix the issue!!! – A. Vreeswijk Apr 07 '22 at 07:18
  • Where is the full error? – Arnav Thorat Apr 12 '22 at 19:30

0 Answers0