Postgresql-locks
PostgreSQL-ロック
_Locks_または_Exclusive Locks_または_Write Locks_は、ユーザーが行またはテーブル全体を変更できないようにします。 UPDATEおよびDELETEによって変更された行は、トランザクションの間、自動的に排他的にロックされます。 これにより、トランザクションがコミットまたはロールバックされるまで、他のユーザーが行を変更できなくなります。
ユーザーが他のユーザーを待つ必要があるのは、同じ行を変更しようとしているときだけです。 異なる行を変更する場合、待つ必要はありません。 SELECTクエリは待つ必要はありません。
データベースは自動的にロックを実行します。 ただし、場合によっては、ロックを手動で制御する必要があります。 手動ロックは、LOCKコマンドを使用して実行できます。 トランザクションのロックタイプとスコープを指定できます。
LOCKコマンドの構文
LOCKコマンドの基本的な構文は次のとおりです-
LOCK [ TABLE ]
name
IN
lock_mode
- name -ロックする既存のテーブルの名前(オプションでスキーマ修飾)。 テーブル名の前にONLYを指定すると、そのテーブルのみがロックされます。 ONLYが指定されていない場合、テーブルとそのすべての子テーブル(存在する場合)がロックされます。
- lock_mode -ロックモードは、このロックが競合するロックを指定します。 ロックモードが指定されていない場合、最も制限的なモードであるACCESS EXCLUSIVEが使用されます。 可能な値は次のとおりです。ACCESSSHARE、ROW SHARE、ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE。
'_取得されると、現在のトランザクションの残りの間ロックが保持されます。 UNLOCK TABLEコマンドはありません。ロックは常にトランザクション終了時に解放されます。_
デッドロック
デッドロックは、2つのトランザクションが互いの操作を完了するのを待っているときに発生する可能性があります。 PostgreSQLはそれらを検出してROLLBACKで終了できますが、デッドロックは依然として不便です。 アプリケーションでこの問題が発生しないようにするには、同じ順序でオブジェクトをロックするように設計してください。
アドバイザリーロック
PostgreSQLは、アプリケーション定義の意味を持つロックを作成する手段を提供します。 これらは_advisory locks_と呼ばれます。 システムはそれらの使用を強制しないので、それらを正しく使用するのはアプリケーション次第です。 アドバイザリロックは、MVCCモデルに不適合なロック戦略に役立ちます。
たとえば、アドバイザリロックの一般的な使用法は、いわゆる「フラットファイル」データ管理システムに典型的な悲観的なロック戦略をエミュレートすることです。 テーブルに保存されたフラグは同じ目的に使用できますが、アドバイザリロックはより高速で、テーブルの膨張を防ぎ、セッションの終了時にサーバーによって自動的にクリーンアップされます。
例
次のようなレコードを持つテーブルlink:/postgresql/company.sql [COMPANY]を考慮してください-
testdb# select * from COMPANY;
id | name | age | address | salary
----+-------+-----+-----------+--------
1 | Paul | 32 | California| 20000
2 | Allen | 25 | Texas | 15000
3 | Teddy | 23 | Norway | 20000
4 | Mark | 25 | Rich-Mond | 65000
5 | David | 27 | Texas | 85000
6 | Kim | 22 | South-Hall| 45000
7 | James | 24 | Houston | 10000
(7 rows)
次の例では、ACCESS EXCLUSIVEモードでtestdbデータベース内のCOMPANYテーブルをロックします。 LOCKステートメントは、トランザクションモードでのみ機能します-
testdb=#BEGIN;
LOCK TABLE company1 IN ACCESS EXCLUSIVE MODE;
上記のPostgreSQLステートメントは、次の結果を生成します-
LOCK TABLE
上記のメッセージは、トランザクションが終了するまでテーブルがロックされていることを示しており、トランザクションを終了するには、トランザクションをロールバックまたはコミットする必要があります。