sql >> Database >  >> RDS >> Mysql

Node.js mysql-transactie

Bijwerken

Zie de bewerking hieronder voor asynchrone/wacht-syntaxis

Ik heb wat tijd besteed aan het schrijven van een gegeneraliseerde versie van het transactievoorbeeld gegeven door node mysql, dus ik dacht dat ik het hier zou delen. Ik gebruik Bluebird als mijn beloftebibliotheek en gebruikte het om het verbindingsobject te 'beloven', wat de asynchrone logica aanzienlijk vereenvoudigde.

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

Als u pooling wilt gebruiken zoals u in de vraag suggereerde, kunt u eenvoudig de createConnection wijzigen regel met myPool.getConnection(...) , en verander de connection.end regels met connection.release() .

Bewerken

Ik heb nog een iteratie van de code gemaakt met behulp van de mysql2 bibliotheek (dezelfde api als mysql maar met belofte-ondersteuning) en de nieuwe async/wait-operators. Hier is dat

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 SOUNDEX() Voorbeelden

  2. Hoe verander je het SQL-isolatieniveau van Python met MySQLdb?

  3. Is een 'blackhole'-tafel slecht?

  4. Tuples worden niet opeenvolgend in de databasetabel ingevoegd?