PostgreSQL - ロック:入門ガイド
こんにちは、未来のデータベース魔术師たち!今日は、PostgreSQLのロックの世界に踏み出す興奮的な旅に出ます。コードを書いたことがない方も心配しないでください。この冒険のなかで、私があなたの親切な案内役として、多年間の教育経験を生かして、すべてのステップを理解していただけるようにサポートします。
ロックとは?
本題に入る前に、シンプルな類似を考えてみましょう。図書館にいるとします。あなたが本を棚から取り出し、それを読んでいる間、他の誰もその同じ本を借りることができません。データベースでのロックも基本的に同じです。複数のユーザーが同時に同じデータを変更することを防ぎ、混乱やエラーを避けるためのものです。
PostgreSQLにおけるロックの種類
PostgreSQLは、データへの並行アクセスを管理するために、さまざまな種類のロックを使用しています。以下に主要な種類を示した表があります。
ロックタイプ | 説明 |
---|---|
行レベルロック | 同時に変更されることを防ぐために、個々の行を保護します |
テーブルレベルロック | 特定の操作に対して、 entire tablesを保護します |
議定ロック | アプリケーション固有の目的のためのユーザー定義ロック |
それでは、これらについて詳しく見ていきましょう!
行レベルロック
行レベルロックは最も一般的な種類です。テーブルのデータを変更すると自動的に適用されます。
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
-- id = 1の行は現在ロックされています
COMMIT;
この例では、アカウント1の残高を更新し始めたときに、PostgreSQLは自動的にその行をロックします。他のトランザクションがコミットする前に同じ行を変更しようとすると、待機します。
テーブルレベルロック
テーブルレベルロックは、全体のテーブルを保護します。一般的ではありませんが、全体のテーブルに影響を与える操作を行う際に必要になることがあります。
BEGIN;
LOCK TABLE accounts IN EXCLUSIVE MODE;
-- 整個のaccountsテーブルが現在ロックされています
UPDATE accounts SET interest_rate = interest_rate + 0.01;
COMMIT;
このコードは、 entire accounts
テーブルをロックし、すべての行を更新します。まるで、整个本棚に「邪魔しないでください」というサインを张贴するようなものです!
デッドロック
それでは、少し難しい話題に移りましょう:デッドロック。 imagine two people each holding a book that the other person wants. 彼らは他の本を手に入れるまで読み続けることができず、しかし、誰も現在の本を手放しません。それはデッドロックです!
PostgreSQLでは、二つのトランザクションがお互いにロックを解放するのを待っている場合にデッドロックが発生することがあります。以下に例を示します。
-- トランザクション1
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- 同時に実行されるトランザクション2
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 2;
UPDATE accounts SET balance = balance + 100 WHERE id = 1;
これらのトランザクションが同時に実行されると、デッドロックが発生する可能性があります:トランザクション1はアカウント1にロックをかけ、アカウント2を待ちますが、トランザクション2はアカウント2にロックをかけ、アカウント1を待ちます。
幸いなことに、PostgreSQLはデッドロックを検出し、状況を解決するために自動的に一つのトランザクションをキャンセルします。図書館の司書が本の交換を解決するようなものです!
議定ロック
最後に、議定ロックについて話しましょう。これらは特別なロックで、あなた、開発者がいつ使用するか決められます。まるで、図書館で自分の「邪魔しないでください」というサインを作成するようなものです!
以下に議定ロックの使用例を示します。
-- 議定ロックを取得
SELECT pg_advisory_lock(123);
-- ここで作業を行います...
-- ロックを解放
SELECT pg_advisory_unlock(123);
この例では、123
はあなたが選んだ任意の番号で、ロックを特定するために使用されます。同じ番号のロックを取得しようとする他のプロセスは、あなたが解放するまで待機します。
議定ロックは、特定のデータベースオブジェクトに結びついていないアプリケーションの活動を調整するのに非常に便利です。たとえば、バッチジョブが同時に一つだけ実行されるようにするために使用することができます。
結論
そして、皆さん!私たちはPostgreSQLのロックの世界を旅しました。一般的な行レベルロックから、デッドロックやカスタマイズ可能な議定ロックまで、さまざまな概念を学びました。ロックは、データベースの交通信号灯のように、すべてがスムーズに運行され、クラッシュを防ぐために役立ちます。
PostgreSQLの冒険を続ける中で、ロックに関連するより複雑なシナリオに直面することでしょう。しかし、この基礎を得ているので、これらの課題を乗り越える準備ができています。練習を続け、好奇心を持ち、快適なコーディングを楽しんでください!
Credits: Image by storyset