sql >> Databáze >  >> RDS >> Mysql

Transakce Node.js mysql

Aktualizovat

Syntaxi async/await naleznete v úpravě níže

Strávil jsem nějaký čas psaním zobecněné verze příkladu transakce poskytnutého uzlem mysql, takže jsem si myslel, že to zde budu sdílet. Používám Bluebird jako svou knihovnu slibů a použil jsem ji k „slíbení“ objektu připojení, což velmi zjednodušilo asynchronní logiku.

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

Pokud byste chtěli používat sdružování, jak jste navrhovali v otázce, můžete snadno přepnout createConnection řádek s myPool.getConnection(...) a přepněte connection.end řádky s connection.release() .

Upravit

Udělal jsem další iteraci kódu pomocí mysql2 knihovna (stejné rozhraní API jako mysql ale s podporou slibu) a novými operátory async/wait. Tady je to

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. Odstraňte data pomocí funkce s hodnotou tabulky na serveru SQL Server

  2. Potřebuji auto_increment pole v MySQL, které není primární klíč

  3. Dynamický aktualizační dotaz PHP PDO do MYSQL

  4. Příkaz SQL CASE:Co to je a jaké jsou nejlepší způsoby jeho použití?