Yushi's Tech Blog
2026-06-24

DBのトランザクションとロック

現場の Web アプリケーション開発において重要な「トランザクション」「ロック」の概念・使い方・SQL 例を網羅的に解説。

🧱 1. トランザクションとは

  • データベースにおける一連の処理の単位
  • 整合性を保証するための不可欠な機構
  • ACID 特性(後述)に従う

🧪 2. ACID 特性

  • Atomicity(原子性): 全処理が成功 or 全て無効
  • Consistency(一貫性): データの整合性を保つ
  • Isolation(独立性): 他トランザクションの影響を遮断
  • Durability(永続性): コミット後の変更は保持される

🔹 3. トランザクションの基本構文(SQL)

START TRANSACTION;
-- 任意の処理
COMMIT;    -- 正常終了
ROLLBACK;  -- 異常終了

🤯 4. トランザクション分離レベル(Isolation Level)

分離レベル 特徴 ユースケース例
READ UNCOMMITTED ダーティリードあり、整合性保証なし 基本使わない
READ COMMITTED コミット済みのみ読める ブログ表示系
REPEATABLE READ 同じ SELECT 結果は変わらない(幻影行あり) EC 在庫確認
SERIALIZABLE 完全直列化。最も厳密で低速 金融系処理

🔧 設定例(SQL)

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT stock FROM products WHERE id = 123 FOR UPDATE;
-- 処理
COMMIT;

🔐 5. ロックの種類と用途

排他ロック(Exclusive Lock / X Lock)

  • 他トランザクションの読み書きをブロック
  • 用途: 在庫減算、会員ランク加算
SELECT * FROM products WHERE id = 1 FOR UPDATE;

共有ロック(Shared Lock / S Lock)

  • 読み取りは OK、書き込みは禁止
  • 用途: 安全な読み取り用
-- MySQL
SELECT * FROM products WHERE id = 1 LOCK IN SHARE MODE;

-- PostgreSQL
SELECT * FROM products WHERE id = 1 FOR SHARE;

⚙️ 6. ロックの粒度

  • テーブルロック: 全体に影響、基本非推奨
  • 行ロック: 高い並行性、InnoDB や PostgreSQL で使用
  • ページロック: 一部 DB エンジン内部向け(明示的制御は稀)

🔀 7. ロック競合とデッドロック

  • ロック競合: 同一リソースにアクセスし待ち状態になる
  • デッドロック: 相互にロック取得待ちで停止

✅ 対策

  • ロック取得順序の統一
  • トランザクション時間を短く
  • タイムアウト設定
  • DB の自動デッドロック検知(PostgreSQL/MySQL)

🧠 8. 悲観的ロックと楽観的ロック

悲観的ロック(Pessimistic Locking)

  • 事前にロックしてから処理
  • 高い衝突可能性に備える
START TRANSACTION;
SELECT stock FROM products WHERE id = 123 FOR UPDATE;
UPDATE products SET stock = stock - 1 WHERE id = 123;
COMMIT;

楽観的ロック(Optimistic Locking)

  • 更新時にversion等で競合チェック
  • 軽量・非同期向き
UPDATE