ロックについて

完了

マルチバージョン コンカレンシー制御 (MVCC) は、ほとんどのシナリオに適したコンカレンシー設定を提供します。 ただし、ロック レベルで影響を受ける行を正確に制御する特定のロックがアプリケーションに必要な場合、明示的なロック モードで、このきめ細かい制御が有効になります。

Azure Database for PostgreSQL には、テーブル レベル ロック、行レベル ロック、ページ レベル ロックという 3 種類の明示的ロックがあります。 最初のトランザクションはロックを要求し、受け入れられた場合は、要求されたロックが既存のロックになります。 別のトランザクションが同じデータに対するロックを取得しようとした場合、元のトランザクションと競合しない場合にのみロックが許可されます。

たとえば、2 つのトランザクションで、SELECT ステートメントを使用して同じデータに対するクエリを同時に実行できます。 これらの要求には ACCESS SHARE ロックが使用され、両方とも許可されます。 別のシナリオでは、あるトランザクションは SELECT ステートメントと ACCESS SHARE ロックを使用してデータに対してクエリを実行しますが、それと同時に、別のトランザクションが同じテーブルを削除しようとします。 テーブルを削除するには ACCESS EXCLUSIVE ロックが必要ですが、それはこのシナリオでは許可されません。

テーブルレベルのロック

テーブル レベルのロックは、名前に ROW が付いている場合でも、テーブル全体に対するロックを取得します。 テーブル全体をロックすることは、テーブル自体を変更しようとしている場合に必要になることがあります。または、多数の行レベル ロックを取得するよりも効率的な場合があります。

Azure Database for PostgreSQL には 8 種類のテーブル レベル ロックがあり、それらの種類のロックを取得する SQL コマンドは次のとおりです。

ロック モード 取得方法
ACCESS SHARE SELECT コマンド
ROW SHARE SELECT FOR UPDATE および SELECT FOR SHARE コマンド
ROW EXCLUSIVE UPDATE、DELETE、INSERT の各コマンド
SHARE UPDATE EXCLUSIVE ANALYZE、CREATE INDEX CONCURRENTLY、CREATE STATISTICS、COMMENT ON、REINDEX CONCURRENTLY コマンド、一部の ALTER INDEX および ALTER TABLE コマンド、VACUUM (FULL ではない)
共有 CREATE INDEX (CONCURRENTLY ではない) コマンド
SHARE ROW EXCLUSIVE CREATE TRIGGER コマンドと一部の ALTER TABLE コマンド
EXCLUSIVE REFRESH MATERIALIZED VIEW CONCURRENTLY コマンド
ACCESS EXCLUSIVE DROP TABLE、REINDEX、TRUNCATE、CLUSTER、REFRESH MATERIALIZED VIEW (CONCURRENTLY ではない) コマンド、ほとんどの ALTER INDEX および ALTER TABLE コマンド、VACUUM FULL

それぞれの既存のロックの種類では、要求された他のロックの取得がロックされます。 次の表に、他のロックの取得をブロックするロックを示します。

-- 既存の ACCESS SHARE 既存の ROW SHARE 既存の ROW EXCLUSIVE 既存の SHARE UPDATE EXCLUSIVE 既存の SHARE 既存の SHARE ROW EXCL 既存の EXCLUSIVE 既存の ACCESS EXCLUSIVE
要求された ACCESS SHARE Blocked
要求された ROW SHARE Blocked Blocked
要求された ROW EXCLUSIVE Blocked Blocked Blocked Blocked
要求された SHARE UPDATE EXCLUSIVE Blocked Blocked Blocked Blocked Blocked
要求された SHARE Blocked Blocked Blocked Blocked Blocked
要求された SHARE ROW EXCLUSIVE Blocked Blocked Blocked Blocked Blocked Blocked
要求された EXCLUSIVE Blocked Blocked Blocked Blocked Blocked Blocked Blocked
要求された ACCESS EXCLUSIVE Blocked Blocked Blocked Blocked Blocked Blocked Blocked Blocked

行レベルのロック

行レベルのロックはより細かく、同じ行にアクセスしている別のトランザクションにのみ影響します。 このロックの種類によりコンカレンシーが向上しますが、多数のロックを取得、削除することはパフォーマンスに悪影響を及ぼします。 行レベルのロックは PostgreSQL によって自動的に取得され、手動では適用されません。

Azure Database for PostgreSQL には 4 種類の行レベル ロックがあり、ブロックする必要がある他のロックの種類に応じて取得されます。

-- 既存の FOR KEY SHARE 既存の FOR SHARE 既存の FOR NO KEY UPDATE 既存の FOR UPDATE
要求された KEY SHARE Blocked
要求された FOR SHARE Blocked Blocked
要求された FOR NO KEY UPDATE Blocked Blocked Blocked
要求された FOR UPDATE Blocked Blocked Blocked Blocked

ページ レベルのロック

ページ レベルのロックは、複数の行で通常は構成されるデータ ページに影響します。 PostgreSQL プロセスではページ レベルのロックが使用されますが、通常、アプリケーション開発者はこの種類のロックを必要としません。

ロックを手動で適用し、現在のロックを表示する

テーブル レベルのロックを手動で適用するには、LOCK コマンドを必要なロック モードで使用します。 LOCK コマンドはトランザクション内に存在する必要があり、トランザクションの完了時にロックが解放されます。 次に例を示します。

BEGIN TRANSACTION;
LOCK TABLE humanresources.department IN ROW EXCLUSIVE MODE;
COMMIT;

データベースで現在保持されているロックを表示するには、pg_locks を使用します。 たとえば、すべての現在のロックを表示するには、次のコマンドを使用します。

SELECT * FROM pg_locks;