mysql2というnpmパッケージを使うと、簡単にトランザクションが実装できます。

まずはパッケージのインストール

npm install --save mysql2

--saveパラメーターを使うことで、package.jsonに保存されます。Gitなどを使えば、他のメンバーはnpm installだけで、mysql2が入れるようになります。

Poolオブジェクト作成

ファイルパス:src/config/mysql.js

const mysql = require('mysql2');

const MySQLConn = {
    getPool() {
        if (!this.pool) {
            this.pool = mysql.createPool({
                host: 'localhost',
                port: 3306,
                user: 'root',
                password: 'password123',
                database: 'test',
                waitForConnections: true,
                connectionLimit: 10,
                queueLimit: 0
            });
        }

        return this.pool.promise();
    },
};

module.exports = MySQLConn;

上記が宣言したpoolオブジェクトを呼び出して、トランザクションを開始します。

ファイルパス:src/model/testModel.js

const MySqlConn = require('../config/mysql');

const ModelTest = {
    async delete(id) {
        const pool = MySqlConn.getPool();
        const conn = await pool.getConnection();
        try {
            await conn.beginTransaction();

            await conn.query(`DELETE FROM table_1 WHERE contentId=1`, id);

            await conn.query(`DELETE FROM table_2 WHERE contentId=1`, id);

            await conn.query(`DELETE FROM table_3 WHERE contentId=1`, id);

            await conn.query(`INSERT INTO table_log (id, value) VALUES(?, ?)`, [id, value]);

            await conn.commit();
        } catch (ex) {
            await conn.rollback();
            return null;
        } finally {
            conn.release();
        }

        return id;
    }
};

module.exports = ModelTest;

トランザクションを使う場合は

await conn.beginTransaction()await conn.commit()の中、自由にクエリ追加することができます。

注意しないといけないことは下記です。

  • 最後にconnectionオブジェクトをリリースこと conn.release()。そうしないと、メモリリーク原因になります。

  • try/catchで例外を処理します。その時は、トランザクションをロールバックしないといけません。await conn.rollback()で実行します。

  • await/asyncを使うことで、簡潔かつコールバックなく、わかりやすいソースコードがかけます。