PostgreSQLでロックが発生する典型パターンを完全解説!初心者でもわかる同時実行制御の基本
生徒
「PostgreSQLを使っていると、ロックで止まるって聞くんですが、どんなときに起こるんですか?」
先生
「ロックは、同じデータを同時に触らないようにするための仕組みです。特定の操作をすると自然に発生します。」
生徒
「難しそうですが、パソコンが苦手でも理解できますか?」
先生
「大丈夫です。紙の名簿を何人かで同時に書き込む場面を想像しながら説明します。」
1. SQLとは何か?
SQLは、データベースという「たくさんの情報を表の形で保存する箱」に指示を出すための言葉です。 紙の名簿を探したり、書き足したり、消したりする作業を、パソコンの中で行うために使います。
PostgreSQLは、このSQLを使って操作できるデータベースで、 多くの人が同時に使っても安全に動くように作られています。 その安全を支えている仕組みの一つが「ロック」です。
2. ロックとは何か?
ロックとは、「今このデータは使っていますよ」という目印のようなものです。 誰かが書き込み中の場所に、別の人が同時に書き込むと、 内容がぐちゃぐちゃになってしまいます。
そこでPostgreSQLは、必要なときだけロックをかけて、 データを守りながら処理を進めます。 ロックは悪いものではなく、安全のための仕組みです。
3. ロックが発生しやすい典型パターン
PostgreSQLでは、特定の操作をすると必ずロックが発生します。 ここでは、初心者がつまずきやすい代表的なパターンを紹介します。
4. UPDATE文を実行したとき
UPDATEは、既存のデータを書き換える操作です。 このとき、対象となる行にロックがかかります。
これは、同じ行を別の人が同時に変更しないようにするためです。
id | name | age | email
---+------------+-----+-------------------
1 | 山田太郎 | 25 | taro@example.com
2 | 佐藤花子 | 19 | hanako@example.com
3 | 鈴木一郎 | 30 | ichiro@example.com
4 | 高橋次郎 | 22 | jiro@example.com
UPDATE users
SET age = 26
WHERE id = 1;
id | name | age | email
---+------------+-----+-------------------
1 | 山田太郎 | 26 | taro@example.com
2 | 佐藤花子 | 19 | hanako@example.com
3 | 鈴木一郎 | 30 | ichiro@example.com
4 | 高橋次郎 | 22 | jiro@example.com
この間、同じ行を更新しようとした別の処理は、 ロックが外れるまで待たされます。
5. DELETE文を実行したとき
DELETEもロックが発生する典型例です。 データを消す操作は、とても強い影響を持つため、 対象の行をしっかりロックします。
DELETE FROM users
WHERE id = 2;
id | name | age | email
---+------------+-----+-------------------
1 | 山田太郎 | 26 | taro@example.com
3 | 鈴木一郎 | 30 | ichiro@example.com
4 | 高橋次郎 | 22 | jiro@example.com
実際にはすぐに消えるのではなく、 「消された」という印を付ける形ですが、 処理中はロックがかかります。
6. INSERT文を実行したとき
INSERTは新しい行を追加する操作です。 一見ロックと関係なさそうですが、 テーブル自体にはロックがかかります。
これは、同時にたくさんの追加が行われても、 データの整合性を保つためです。
INSERT INTO users (id, name, age, email)
VALUES (5, '中村健', 28, 'ken@example.com');
id | name | age | email
---+------------+-----+-------------------
1 | 山田太郎 | 26 | taro@example.com
3 | 鈴木一郎 | 30 | ichiro@example.com
4 | 高橋次郎 | 22 | jiro@example.com
5 | 中村健 | 28 | ken@example.com
7. トランザクションを長く使ったとき
トランザクションとは、複数の操作をまとめて行う仕組みです。 途中で失敗したら、全部なかったことにできます。
しかし、トランザクションを長時間開いたままにすると、 ロックも長時間残ります。 これがロック待ちの原因になることがあります。
8. SELECTでもロックが発生する場合
PostgreSQLでは、普通のSELECTではロックはほとんど発生しません。 ただし、特別な書き方をするとロックがかかります。
SELECT *
FROM users
WHERE id = 1
FOR UPDATE;
FOR UPDATEは、「この行を後で更新する予定です」という意味です。 そのため、他の更新処理を待たせるロックが発生します。
9. 初心者が意識しておきたいポイント
ロックは、UPDATE、DELETE、INSERTなどの 「書き込み系の操作」で必ず発生します。
PostgreSQLは、読む処理を止めにくい設計ですが、 書く処理同士はロックで順番待ちになります。
「誰かが書いている間は、順番を待つ」 という考え方を持つと、ロックの動きが理解しやすくなります。