PostgreSQL TRANSACTION(トランザクション)
トランザクション(TRANSACTION)は、データベース管理システムの実行プロセスにおける論理的な単位であり、限られたデータベース操作のシーケンスで構成されます。
データベーストランザクションは通常、データベースへの読み取り/書き込み操作のシーケンスを含みます。次の2つの目的があります。
- データベース操作シーケンスに対して、障害から正常状態に回復する方法を提供し、同時に、データベースが異常な状態でも一貫性を維持できる方法を提供します。
- 複数のアプリケーションがデータベースに同時にアクセスする場合、これらのアプリケーション間で分離方法を提供し、互いの操作が干渉し合うのを防ぐことができます。
トランザクションがデータベース管理システム(DBMS)にコミットされると、DBMS はそのトランザクション内のすべての操作が正常に完了し、その結果がデータベースに永続的に保存されることを保証する必要があります。トランザクション内の一部の操作が正常に完了しなかった場合、トランザクション内のすべての操作をロールバックして、トランザクション実行前の状態に戻す必要があります。同時に、そのトランザクションはデータベースや他のトランザクションの実行に影響を与えず、すべてのトランザクションは独立して実行されているかのように見えます。
トランザクションの属性
トランザクションには、次の4つの標準的な属性があります。通常、頭文字をとって ACID と呼びます。
- 原子性(Atomicity):トランザクションは全体として実行され、含まれるデータベース操作はすべて実行されるか、すべて実行されないかのどちらかです。
- 一貫性(Consistency):トランザクションは、データベースの状態がある一貫した状態から別の一貫した状態に移行することを保証する必要があります。一貫した状態とは、データベース内のデータが整合性制約を満たすことを意味します。
- 分離性(Isolation):複数のトランザクションが並行して実行される場合、あるトランザクションの実行は他のトランザクションの実行に影響を与えるべきではありません。
- 永続性(Durability):コミットされたトランザクションによるデータベースへの変更は、データベースに永続的に保存されるべきです。
例
ある人が店で電子マネーを使って100元の買い物をする場合、少なくとも次の2つの操作が含まれます。
- その人の口座から100元減算されます。
- 店の口座に100元加算されます。
トランザクションをサポートするデータベース管理システムは、上記の2つの操作(「トランザクション」全体)がすべて完了するか、一緒にキャンセルされることを保証します。そうでないと、100元が突然消えたり現れたりする状況が発生します。
トランザクション制御
以下のコマンドを使用してトランザクションを制御します:
- BEGIN TRANSACTION:トランザクションを開始します。
- COMMIT:トランザクションを確定します。または END TRANSACTION コマンドを使用できます。
- ROLLBACK:トランザクションをロールバックします。
トランザクション制御コマンドは、INSERT、UPDATE、DELETE でのみ使用できます。テーブルの作成や削除では使用できません。これらの操作はデータベースで自動的にコミットされるためです。
BEGIN TRANSACTION コマンド
トランザクションは、BEGIN TRANSACTION コマンドまたは単純な BEGIN コマンドを使用して開始できます。このようなトランザクションは通常、次の COMMIT または ROLLBACK コマンドに遭遇するまで実行され続けます。ただし、データベースがシャットダウンされたり、エラーが発生した場合、トランザクション処理もロールバックされます。以下は、トランザクションを開始するための簡単な構文です:
BEGIN; 或者 BEGIN TRANSACTION;
COMMIT コマンド
COMMIT コマンドは、トランザクションによる変更をデータベースに保存するためのトランザクションコマンドです。つまり、トランザクションを確定します。
COMMIT コマンドの構文は次のとおりです:
COMMIT; 或者 END TRANSACTION;
ROLLBACK コマンド
ROLLBACK コマンドは、まだデータベースに保存されていないトランザクションを元に戻すためのトランザクションコマンドです。つまり、トランザクションをロールバックします。
ROLLBACK コマンドの構文は次のとおりです:
ROLLBACK;
実例
COMPANY テーブルを作成します(COMPANY SQL ファイルをダウンロード)。データ内容は次のとおりです:
サンプルdb# 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)
では、トランザクションを開始し、テーブルから age = 25 のレコードを削除します。最後に、ROLLBACK コマンドを使用してすべての変更を元に戻します。
サンプルdb=# BEGIN; DELETE FROM COMPANY WHERE AGE = 25; ROLLBACK;
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
では、別のトランザクションを開始し、テーブルから age = 25 のレコードを削除します。最後に、COMMIT コマンドを使用してすべての変更をコミットします。
サンプルdb=# BEGIN; DELETE FROM COMPANY WHERE AGE = 25; COMMIT;
COMPANY テーブルを確認すると、レコードが削除されています:
id | name | age | address | salary ----+-------+-----+------------+-------- 1 | Paul | 32 | California | 20000 3 | Teddy | 23 | Norway | 20000 5 | David | 27 | Texas | 85000 6 | Kim | 22 | South-Hall | 45000 7 | James | 24 | Houston | 10000 (5 rows)その他の拡張