【Express】TypeORMを使ってトランザクション処理をつくろう!【Node.js】

Node.js

みなさんこんにちは、現役エンジニアのサメハックです

未経験からWebエンジニアに転職し、
正社員として5年働いたのちフリーランスとして独立しました。

Node.jsの解説シリーズです。

今回はTypeORMを使ったトランザクション処理の作り方について学んでいきましょう!

駆け出しエンジニアや未経験の方、
また新入社員を指導する先輩社員にとっても
わかりやすいように解説していきます!

この記事を読むと・・・
  • Node.jsでTypeORMを使ってトランザクション処理が実装できる
本記事ではTypeScriptで記述するよ!

TypeORMでトランザクション処理を実装しよう

トランザクションとは

トランザクションとは複数のデータベース操作を1つのまとまりとして扱う仕組みです。

複数の処理を1まとまりとして扱うことで
途中で問題が発生した場合に、操作を切り戻してデータの矛盾や損失を防ぐ/strong>ことができます。

例えば、銀行取引を考えてみましょう。
送金トランザクションでは、まず自分のアカウントからお金を引き出し、
次に相手のアカウントにそのお金を挿入します。
もし途中でエラーが発生した場合、お金がどこかに消えてしまいます。

これを防ぐためにトランザクションが使われます。
成功 → お金の移動が確定します。
失敗 → 何も変更されない状態が維持されます。

複数の操作を1まとまりにして、どこかで以上があった場合に
それまでの操作をなかったことにする仕組みだよ!

TypeORMでトランザクションを行う構文

import { getManager } from "typeorm";

// トランザクションを開始
const entityManager = getManager();
await entityManager.transaction(async (transactionalEntityManager) => {
    await transactionalEntityManager.getRepository(エンティティ1).save(データ);
    await transactionalEntityManager.getRepository(エンティティ2).save(データ);
    await transactionalEntityManager.getRepository(エンティティ3).save(データ);
    await transactionalEntityManager.getRepository(エンティティ4).save(データ);
});
エンティティ1〜4すべての更新に成功した場合にCOMMITされ、
どちらかが失敗した場合にはROLLBACKするよ!

トランザクション処理を実装しよう!

以下の操作を実行します

  • テーブル1にデータを追加
  • テーブル1の最新のIDを取得し、テーブル2の値に設定
  • テーブル2を更新
テーブル1.idとテーブル2.joinToTable1でリレーションする前提だよ!

import express from "express";
import { getManager } from "typeorm";

// エンティティのインポート
import Table1 from "../entities/Table1";
import Table2 from "../entities/Table2";

const router = express.Router();

// POSTリクエストを処理するエンドポイントの例
router.post("/", async (req, res) => {
  // トランザクションを開始
  const entityManager = getManager();
  await entityManager.transaction(async (transactionalEntityManager) => {
    // テーブル1を取得
    const table1Repository = transactionalEntityManager.getRepository(Table1);

    // データの作成
    const table1Data = table1Repository.create({
      /* データ設定 */
    });

    // テーブル1更新
    // ※成功した場合のidを取得するために戻り値を受け取っています。
    const newTable1Data = await table1Repository
      .getRepository(Table1)
      .save(table1Data);

    // テーブル2を取得
    const table2Repository = transactionalEntityManager.getRepository(Table2);

    // データの作成
    const table2Data = table1Repository.create({
      /* データ設定 */
      joinToTable1: newTable1Data.id,
    });

    // テーブル2更新
    await table2Repository.getRepository(Table1).save(table1Data);
  });

  return res.status(200).send();
});

export default router;
トランザクション処理が実装できたよ!
テーブル1、テーブル2双方の更新に成功した場合にCOMMITされ、
どちらかが失敗した場合にはROLLBACKするよ!

まとめ

  • トランザクションとは複数のデータベース操作を1つのまとまりとして扱う仕組み
  • すべての更新に成功した場合にCOMMITされ、どちらかが失敗した場合にはROLLBACKする

満足いただけたら、1クリックなのでSNSフォローしてもらえると嬉しいです🦈

タイトルとURLをコピーしました