sql >> データベース >  >> RDS >> Mysql

Node.jsmysqlトランザクション

    更新

    async / await構文については、以下の編集を参照してください

    ノードmysqlによって提供されるトランザクション例の一般化されたバージョンを書くのにしばらく時間を費やしたので、ここでそれを共有しようと思いました。私はBluebirdをpromiseライブラリとして使用しており、非同期ロジックを大幅に簡素化する接続オブジェクトを「約束」するために使用しました。

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

    質問で提案したようにプーリングを使用したい場合は、createConnectionを簡単に切り替えることができます。 myPool.getConnection(...)の行 、connection.endを切り替えます connection.release()の行 。

    編集

    mysql2を使用してコードをもう一度繰り返しました ライブラリ(mysqlと同じAPI ただし、promiseサポート付き)および新しいasync/await演算子。これが

    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_*関数をPDOおよびプリペアドステートメントに置き換える

    2. SQLでは常に小数点以下の桁数を表示しますか?

    3. MySQLトリガーの使用

    4. MySQL:左結合を実行して、結合テーブルから1行だけをプルできますか?