sql >> Databasteknik >  >> RDS >> Mysql

Node.js mysql transaktion

Uppdatera

Se redigeringen nedan för syntax för asynkron/avvakta

Jag tillbringade lite tid med att skriva en generaliserad version av transaktionsexemplet från node mysql, så jag tänkte att jag skulle dela det här. Jag använder Bluebird som mitt löftesbibliotek och använde det för att "lova" anslutningsobjektet vilket förenklade den asynkrona logiken mycket.

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

Om du ville använda pooling som du föreslog i frågan kan du enkelt byta createConnection rad med myPool.getConnection(...) , och byt connection.end rader med connection.release() .

Redigera

Jag gjorde ytterligare en iteration av koden med mysql2 bibliotek (samma api som mysql men med löftesstöd) och de nya async/wait-operatörerna. Här är 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. Upprätthålla ett grupperat löpande MAX (eller MIN)

  2. Ta bort dubbletter från Count()-resultat i SQLite

  3. MySQL Visa användare

  4. SQLSTATE[HY000] [1698] Åtkomst nekad för användaren 'root'@'localhost'