データベース PostgreSQL トランザクション
トランザクション
SAVEPOINT
トランザクションでROLLBACK文ではとトランザクション全体が取り消されたが、セーブポイント機能を使って一部だけ実行を取りけり、トランザクションを継続することができる。SAVEPOINTは、PostgreSQL 8.0から加わった機能。
SAVEPOINT savepoint_name ROLLBACK [TO SAVEPOINT savepoint_name] RELEASE [SAVEPOINT] savepoint_name
モードと隔離レベル
トランザクションには、モードと隔離レベルという2つの属性がある。モード
隔離レベル
これらは、トランザクション開始時に指定可能。
BEGIN文のオプション、BEGIN直後のSET TRANSACTION文で設定できる。
指定しなかった場合は、default_transaction_read_only, default_transaction_isolationの設定が適用される。
インストール後の既定値はモードは「READ WRITE」、隔離レベルは、「READ COMMITTED」が設定されている。
同時実行制御
トランザクション隔離レベル
標準SQLでは、トランザクション隔離レベルを3つの「望ましくない現象」がおきるかどうかによって定義している。
ダーティーリード | 同時に実行されている別のトランザクションが書き込んで、今COMMITしていないデータを読み込んでしまう |
反復不能読み取り | トランザクションが反復して同じデータを読み込むとき、別のトランザクションがそのデータを更新してCOMMITしたために、同じデータを読んでいるにも関わらず、異なる結果を得てしまう。 |
ファントムリード | トランザクションがある検索条件で問い合わせを再実行したときに、別のトランザクションが書き込みをしてCOMMITしたために、同じ検索条件で問い合わせを実行したにも関わらず異なる結果を得てしまう。 |
トランザクション隔離レベル
隔離レベル | ダーティーリード | 反復不能読み取り | ファントムリード |
READ UNCOMMITTED | 起きる | 起きる | 起きる |
READ COMMITTED | 起きない | 起きる | 起きる |
REPEATABLE READ | 起きない | 起きない | 起きる |
起きない | 起きない | 起きない | 起きない |
PostgreSQLでは、READ COMMITTEDレベルとSERIALIZABLEレベルをサポートしている。
PostgreSQLでは、トランザクション隔離レベルをSERIALIZABLEにした場合、同一トランザクション中に同じレコードを同時に更新すると、どちらかのトランザクションがエラーになり、ロールバックする。アプリケーション側では、そのシリアライゼーション失敗のエラーに対して再度実行する仕組みを作る必要がある。
ロック
PostgreSQLでは、トランザクション内で行の更新を行うと、レコードロックがかかる。更新を終了するまで、他のトランザクションによるそのレコードの更新は待たされる。DELETEやUPDATEなどの操作は伴わず、レコードロックだけをかけるには「SELECT 〜 FOR UPDATE」を使う。末尾にFOR UPDATE句をつけたSELECT文を実行すると、選択されたレコードにレコードロックがかかる。
レコードロックを使う方式は、ブロックされることはあっても、トランザクション失敗時のやり直しをアプリケーション側で実装する必要がなくなる。
SELECT * FROM MYTABLE <B>FOR UPDATE</B>;
テーブルロック
LOCK [TABLE] table_name [IN lock_mode MODE] [NOWAIT]
table_name | テーブル名 |
lock_mode | ロックモード |
NOWAIT | ロックが取得でないとき、待たずにエラーを返す |
ロックモード | 取得する主なSQL | 競合するモード |
ACCESS SHARE | SELECT, ANALYZE | |
ROW SHARE | SELECT FOR UPDATE | |
ROW EXCLUSIVE | UPDATE, DELETE, INSERT | |
SHARE UPDATE EXCLUSIVE | VACCUM | |
SHARE | CREATE INDEX | |
SHARE ROW EXCLUSIVE | LOCK文のみ | |
EXCLUSIVE | LOCK文のみ | |
ACCESS EXCLUSIVE | VACUUM FULL, ALTER TABLE, DROP TABLE, REINDEX, CLUSTER |