sql >> Database teknologi >  >> RDS >> Mysql

Node.js mysql transaktion

Opdater

Se redigeringen nedenfor for async/wait syntaks

Jeg brugte noget tid på at skrive en generaliseret version af transaktionseksemplet givet af node mysql, så jeg tænkte, at jeg ville dele det her. Jeg bruger Bluebird som mit løftebibliotek og brugte det til at 'love' forbindelsesobjektet, hvilket forenklede den asynkrone logik meget.

const Promise = ('bluebird');
const mysql = ('mysql');

/**
 * Run multiple queries on the database using a transaction. A list of SQL queries
 * should be provided, along with a list of values to inject into the queries.
 * @param  {array} queries     An array of mysql queries. These can contain `?`s
 *                              which will be replaced with values in `queryValues`.
 * @param  {array} queryValues An array of arrays that is the same length as `queries`.
 *                              Each array in `queryValues` should contain values to
 *                              replace the `?`s in the corresponding query in `queries`.
 *                              If a query has no `?`s, an empty array should be provided.
 * @return {Promise}           A Promise that is fulfilled with an array of the
 *                              results of the passed in queries. The results in the
 *                              returned array are at respective positions to the
 *                              provided queries.
 */
function transaction(queries, queryValues) {
    if (queries.length !== queryValues.length) {
        return Promise.reject(
            'Number of provided queries did not match the number of provided query values arrays'
        )
    }

    const connection = mysql.createConnection(databaseConfigs);
    Promise.promisifyAll(connection);
    return connection.connectAsync()
    .then(connection.beginTransactionAsync())
    .then(() => {
        const queryPromises = [];

        queries.forEach((query, index) => {
            queryPromises.push(connection.queryAsync(query, queryValues[index]));
        });
        return Promise.all(queryPromises);
    })
    .then(results => {
        return connection.commitAsync()
        .then(connection.endAsync())
        .then(() => {
            return results;
        });
    })
    .catch(err => {
        return connection.rollbackAsync()
        .then(connection.endAsync())
        .then(() => {
            return Promise.reject(err);
        });
    });
}

Hvis du ville bruge pooling, som du foreslog i spørgsmålet, kunne du nemt skifte createConnection linje med myPool.getConnection(...) , og skift connection.end linjer med connection.release() .

Rediger

Jeg lavede endnu en iteration af koden ved hjælp af mysql2 bibliotek (samme api som mysql men med løftestøtte) og de nye async/wait-operatører. Her er det

const mysql = require('mysql2/promise')

/** See documentation from original answer */
async function transaction(queries, queryValues) {
    if (queries.length !== queryValues.length) {
        return Promise.reject(
            'Number of provided queries did not match the number of provided query values arrays'
        )
    }
    const connection = await mysql.createConnection(databaseConfigs)
    try {
        await connection.beginTransaction()
        const queryPromises = []

        queries.forEach((query, index) => {
            queryPromises.push(connection.query(query, queryValues[index]))
        })
        const results = await Promise.all(queryPromises)
        await connection.commit()
        await connection.end()
        return results
    } catch (err) {
        await connection.rollback()
        await connection.end()
        return Promise.reject(err)
    }
}


  1. MySQL CAST som DATO

  2. 2008 R2-fejlrettelsen, der bryder RCSI

  3. LISTAGG-funktion:Resultatet af strengsammenkædning er for lang

  4. SQL Server 2016:Gendan en database