👻

Firebase トランザクション処理

2023/08/08に公開

はじめに

前にバッチ処理を使用する機会があり続けてトランザクション処理についても学習したのでメモ

トランザクション処理とは

  • 1つ以上のドキュメントに対して読み取り/書き込みを行う一連のオペレーションのこと。
  • トランザクションは、任意の数のget()オペレーションと、その後に続く任意の数の書き込みオペレーション(set()、update()、delete() など)で構成されます。
  • 同時に複数のドキュメントを編集する場合、トランザクション全体を再実行します。たとえば、トランザクションがドキュメントを読み取り、別のクライアントがそれらのドキュメントを変更すると、トランザクションを再試行します。この機能により、常に整合性のある最新データに対してトランザクションが実行されます。
  • トランザクションでは、書き込みが部分的に適用されることはなく、成功したトランザクションの完了時にすべての書き込みが実行される。

手順

import { runTransaction } from "firebase/firestore";

try {
  await runTransaction(db, async (transaction) => {
    const docSnap_1 = await transaction.get(doc(db, コレクション名, ドキュメントID));
    const docSnap_2 = await transaction.get(doc(db, コレクション名, ドキュメントID));
    
    if (!docSnap_1.exists() && !docSnap_2.exists()) {
      throw "Document does not exist!";
    }

    transaction.update(docSnap_1, { updated_at: TimeStamp.now() });
    // docSnap_2の書き込みが失敗した場合は、docSnap_1の書き込みはデータベースには保存されない。
    transaction.update(docSnap_2, { updated_at: TimeStamp.now() });
  });
  console.log("Transaction successfully committed!");
} catch (e) {
  console.log("Transaction failed: ", e);
}

注意点

  • 読み取りオペレーションは書き込みオペレーションの前に実行する必要があります。
  • トランザクションが読み取るドキュメントに対して同時編集の影響が及ぶ場合は、トランザクションを呼び出す関数(トランザクション関数)が複数回実行されることがあります。
  • トランザクション関数はアプリケーションの状態を直接変更してはなりません。
  • クライアントがオフラインの場合、トランザクションは失敗します。

まとめ

  • トランザクション処理を使用するのは複数のドキュメントに同時に書き込みを行うときで、書き込むドキュメント同士が整合性のあるデータではいけないときに使用する。
    (例)在庫機能

参考

https://firebase.google.com/docs/firestore/manage-data/transactions?hl=ja

https://zenn.dev/yucatio/articles/7c4ba0d0138ca9

Discussion