さかした
🔄 Next.js × Prisma × Supabase で学ぶ「トランザクション」の基本と実践
2025年05月10日
要約を生成中...
✅ はじめに
アプリ開発で「一部だけ保存されてしまった…」という問題、経験ありませんか?
たとえば:
ユーザー登録とプロフィール作成を同時にしたい
学習記録とカテゴリを同時に作成したい
そんなときに活躍するのが「トランザクション」です。
本記事では、Next.js + Prisma + Supabase 環境を前提に、初心者向けに解説していきます。
💡 トランザクションとは?
複数の処理を「1つのまとまった処理」として扱い、全部成功したときだけデータベースに反映する仕組み
つまり「全部成功する or 全部失敗する」の オール・オア・ナッシングな世界です。
🛠 どんなときに使う?
以下のような「複数のテーブルをまとめて操作する場面」で使います:
usersテーブルに新規登録しつつprofilesテーブルにもデータを追加したい
📦 Prisma のトランザクション構文(基本形)
await prisma.$transaction(async (tx) => { // すべて tx 経由で処理すること! await tx.user.create(...); await tx.profile.create(...);});ここで重要なのは、tx(トランザクション専用のクライアント)を使うことです。
通常の prisma.user.create を使ってしまうと、トランザクションに含まれません。
✍️ 実例:ユーザー登録とプロフィール作成
// /app/api/user/register/route.tsimport { NextRequest, NextResponse } from "next/server";import { prisma } from "@/lib/prisma";export async function POST(req: NextRequest) { const { email, nickname, first_name, last_name } = await req.json(); try { await prisma.$transaction(async (tx) => { const user = await tx.user.create({ data: { email, nickname }, }); await tx.profile.create({ data: { supabaseUserId: user.supabaseUserId, first_name, last_name, }, }); }); return NextResponse.json({ message: "登録成功" }); } catch (error) { console.error("登録エラー:", error); return NextResponse.json( { message: "登録に失敗しました" }, { status: 500 } ); }}このように、tx を通してすべての処理をまとめることで、安全な登録処理が可能になります。
🧠 よくある落とし穴
✅ まとめ
トランザクションは「全部成功 or 全部失敗」の安心設計
Prisma の
$transaction()を使おう中では必ず
txを使ってすべての処理を行うこと
🧪 補足:Supabaseとの関係
Prisma は Supabase の Postgres とも連携可能です。
Supabase の Auth を使っている場合でも、トランザクションで安全にユーザーデータ・プロフィールなどを保存できます。

