1
0

More than 1 year has passed since last update.

[nodejs]mysql2のpool.queryをネストさせたら動かなくなった事象を解消した例

Last updated at Posted at 2023-01-22

何が起きた?

下記のようなロジックを作ったところ、入ってるまで通るけど最後のpool.queryに入らずupdateできないことがありました。

test.js
var mysql = require('mysql2');
const pool = mysql.createPool({
  host: '127.0.0.1',
  user: 'root',
  password: 'password',
  database: 'test_db'
});

// 関数呼び出し
test();

// 呼び出し用の関数準備
function test() {
  pool.query("select * from emails", function (err, factDatas, fields) {
    for (const obj of factDatas) {
      pool.query(`select * from users where id = ${obj.user_id};`, function (err, user_rows, fields) {
        console.log("入ってる");
        pool.query(`update emails set new_user_id = ${user_rows[0].new_id} where user_id = ${obj.user_id};`, function (err, result, fields) {
          if (err) throw err;
          console.log(result);
        });
      });
    }
  });
}

解決方法

下記のように関数を切り出す(分割する)ことで動作しました。

test.js
var mysql = require('mysql2');
const pool = mysql.createPool({
  host: '127.0.0.1',
  user: 'root',
  password: 'password',
  database: 'test_db'
});

// 関数呼び出し
test();

// 呼び出し用の関数準備
function test() {
  pool.query("select * from emails", function (err, factDatas, fields) {
    step1(factDatas);
  });
}
// 分割した
async function step1(factDatas) {
  for (const obj of factDatas) {
    step2(obj);
    await sleep(300); // スリープ処理を追加する
  }
}
// 分割した
function step2(obj) {
  pool.query(`select * from users where id = ${obj.user_id};`, function (err, user_rows, fields) {
    console.log("入ってる");
    step3(user_rows, obj);
  });
}
// 分割した
function step3(user_rows, obj) {
  pool.query(`update emails set new_user_id = ${user_rows[0].new_id} where user_id = ${obj.user_id};`, function (err, result, fields) {
    if (err) throw err;
    console.log(result);
  });
}
// sleep関数を準備
function sleep(time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve();
    }, time);
  });
}

原因の予想

正直挙動を理解しきれていませんが、筆者としては処理が早すぎてupdateのトランザクションで弾かれたか、またはデッドロックになったのではないかと予想しています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0