LoginSignup
10
10

More than 3 years have passed since last update.

【Express + Postgres】非同期とかトランザクションとか考慮したDB接続

Posted at

はじめに

以前にも似たような記事(※)を書いたが、より汎用性のありそうなコードを書く機会があったので、本記事にまとめておく。
おそらく、非同期とかトランザクションとかも考慮しているコードになっているはず…

【Node.js+Express+PostgreSQL】ExpressにPostgreSQLを導入

環境

  • node 10.15
  • express 4.17
  • pg 7.12

サンプルコード

command
npm install --save pg
index.js
const express = require("express");
const pg = require("pg");
const app = express();
const port = 3000;

app.listen(port, () => {
  console.log(`Start server port: ${port}`);
});

const pool = new pg.pool({
  host: "hoge",
  database: "hogehoge",
  user: "hogehogehoge",
  port: 5432,
  password: "hogehogehogehoge"
});

app.post("/register", (req, res) => {
  const id = req.body.post_id;
  ( async () => {
    const client = pool.connect();
    try{
      await client.query("BEGIN");
      let result = await client.query("SELECT name FROM users WHERE id = $1", [id]);
      const user_name = result.rows[0];
      client.query("INSERT INTO teams (member) VALUES ($1)", [user_name]);
      await client.query("COMMIT");
      res.json({
        msg: "Successfully insert data!"
      });
    } catch {
      await client.query("ROLLBACK");
      throw err
    }  finally {
      client.release();
    }
  })().catch( err => {
    console.log(err.stack);
    res.json({
      msg: "Fail to insert data"
    });
  });
});

解説

まず、クライアントから送られてきたpost_idをもとに、usersテーブルからnameを検索。
次に、そのnameteamsテーブルのmember列に保存。
以上が実現したい処理の流れ。

  • const pool = new pg.pool{ ... }の部分で、DB接続情報の設定。
  • Node.jsのDBアクセスは非同期推奨なので、(async () => { ... })とする。
  • const client = await pool.connect();で同期的にDBに接続。
  • 読みやすさ重視でtry{ } catch{ } finally{ }
    • 処理順がわからなかったが、ここが参考になった。
  • トランザクションは、BEGINで始まり、COMMITまたはROLLBACKで終わる。
    • await client.query("BEGIN"); ... await client.query("COMMIT");の場合、これらに囲まれている範囲のSQL文は、正常にデータベースに反映される。
    • await client.query("BEGIN"); ... await client.query("ROLLBACK");の場合、これらに囲まれている範囲のSQL文は、破棄されてデータベースには反映されない。
    • つまり、上記のサンプルコードのように、正常時にはCOMMITで終わるように、エラー時にはROLLBACKで終わるように書けばよい。
  • client.release();は、DB接続を切るみたいな認識(要確認)

おわりに

取り急ぎ、メモとして残したので、抜け漏れなどあるかと。
見つけ次第、随時修正します。

参考サイト

10
10
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
10
10