投稿日:2026/6/19
更新日:2026/6/21

複数のアプリケーションプロセスやCI/CDジョブが、同じDBに対して同時に処理を走らせることがあります。
このとき「同じ処理は同時に1つだけ実行したい」という場面で使えるのが advisory lock です。
アプリケーションが任意の意味を持たせて使うDB側のロック機能です。
通常の行ロックやテーブルロックは、特定のテーブル・行・DDL操作にDBが意味を持たせて管理します。
一方で advisory lock は、ロック対象の意味をDBではなくアプリケーション側が決めます。
たとえば以下のような用途です。
advisory lock の仕組み自体は DBの機能です。
代表例:
pg_advisory_lock, pg_try_advisory_lockGET_LOCK, RELEASE_LOCKsp_getapplockORMやマイグレーションツールは、このDB機能を利用して排他制御します。
つまり「ロック機構そのものはDB」「いつ・何のために使うかはアプリやツール側の実装」です。
特定の行を更新・参照する処理を守るためのロックです。
SELECT *
FROM orders
WHERE id = 1
FOR UPDATE;
この場合、orders テーブルの特定行に対する同時更新を防ぎます。
テーブルや行とは直接関係ない、任意のキーに対するロックです。
SELECT pg_advisory_lock(12345);
この 12345 にどういう意味を持たせるかは、アプリケーション側が決めます。
たとえば 12345 を「日次集計バッチ用のロック」として扱えます。
SELECT pg_advisory_lock(12345);
同じキー 12345 のロックを他のセッションがすでに持っている場合、このSQLは待機します。
SELECT pg_try_advisory_lock(12345);
戻り値が true ならロック取得成功、false なら他のセッションがロック中です。
SELECT pg_advisory_unlock(12345);
PostgreSQLには大きく2種類あります。
SELECT pg_advisory_lock(12345);
SELECT pg_advisory_unlock(12345);
DB接続セッションに紐づくロックです。
明示的に解放するか、接続が切れるまで保持されます。
BEGIN;
SELECT pg_advisory_xact_lock(12345);
-- 処理
COMMIT;
トランザクション終了時に自動で解放されます。
解放漏れを避けたい場合はこちらの方が扱いやすいです。
Prisma Migrate は、マイグレーションの同時実行を防ぐために advisory lock を使います。
対象になる主なコマンド:
prisma migrate deployprisma migrate devprisma migrate resolveたとえばCI/CDで2つのデプロイが同時に走り、両方が prisma migrate deploy を実行すると、同じマイグレーションを同時に適用しようとして不整合が起きる可能性があります。
PrismaはDBの advisory lock を使って、複数のマイグレーションコマンドが同時に進まないようにしています。
Prismaのポイント:
findMany や create のような Prisma Client のクエリに毎回かかるものではないPRISMA_SCHEMA_DISABLE_ADVISORY_LOCK で無効化できるSELECT pg_try_advisory_lock(1001);
true なら処理を開始し、false なら「すでに実行中」として終了します。
CI/CDで複数ジョブが同じDBにマイグレーションをかける可能性がある場合、advisory lock で片方だけ進めます。
たとえば「同じ請求IDに対する再計算処理は同時に1つだけ」にしたい場合、請求IDからロックキーを作って advisory lock を取る設計ができます。
advisory lock は、DBが提供する「任意キーの排他制御」機能です。
行ロックやテーブルロックと違い、ロックキーの意味はアプリケーション側が決めます。
Prismaの advisory lock は、DBの advisory lock 機能を Prisma Migrate が利用しているものです。
主な目的は、マイグレーションの同時実行を防ぐことです。