初めに
データベースを利用するならトランザクションについての理解が必要不可欠。
今回はそんなトランザクションについてまとめていきます。
トランザクションとは
- トランザクションは、データベース操作の処理単位。
- 複数の操作を一つのグループとして扱い、全てが成功するか、全てが失敗するかの「全て成功、または無し」の性質を持つ。
- データの整合性と安全性を保つ。
トランザクションの特徴
-
ACID特性
- 原子性(Atomicity)
トランザクション内の全ての操作が完全に実行されるか、全く実行されないかのどちらかです。 - 一貫性(Consistency)
トランザクションはデータベースの一貫性を保った状態で完了します。 - 隔離性(Isolation)
同時に実行される複数のトランザクションが互いに干渉しないようにします。 - 耐久性(Durability)
トランザクションが完了したら、その結果はシステム障害にも耐える形で永続化されます。
- 原子性(Atomicity)
-
トランザクションの制御
-
BEGIN
でトランザクションを開始し、COMMIT
で確定、ROLLBACK
で取り消しを行います。 - 隔離レベルを設定して、トランザクション間の可視性や影響を制御できます。
-
-
ロック
- データの整合性を保つために、ロックを用いてデータへの同時アクセスを制御します。
- ロックの種類やレベルに応じて、異なる振る舞いがあります。
トランザクションの分離レベルについて
トランザクションが他のトランザクションからどの程度「隔離」されるかを決定する重要な設定。
トランザクションの分離レベルが弱い場合には、ダーティリードや反復不能読み取り、ファントムリードといった影響が発生する。
PostgreSQLでは以下の分離レベルを指定できる。
-
Read Uncommitted
このレベルでは、他のトランザクションがまだコミットしていない変更を見ることができる(ダーティリード)。
ただし、PostgreSQLでは実際にはこのレベルは「Read Committed」と同じ振る舞いをします。 -
Read Committed (デフォルト)
トランザクションは、自分が開始された時点でコミットされているデータのみを見ることができます。
他のトランザクションによる変更がコミットされると、それらの変更が見えるようになります。
これにより、ノンリピータブルリード(同じクエリが異なる結果を返す)は発生する可能性があります。 -
Repeatable Read
トランザクションは、自分が開始された時点のデータのスナップショットを見ます。
これにより、同じクエリはトランザクション中常に同じ結果を返します(ノンリピータブルリードを防止)。
しかし、ファントムリード(他のトランザクションによって新たに追加または削除された行が見えること)は発生する可能性があります。 -
Serializable
最も厳格な分離レベルで、トランザクションが他のトランザクションから完全に隔離されます。
他のトランザクションの影響を一切受けず、データベースに対する一連のトランザクションが逐次的に実行されたかのような振る舞いをします。
ファントムリードも防止されますが、このレベルではパフォーマンスの低下やロック競合が発生しやすくなる可能性があります。
まとめ
- トランザクションは、データベースの信頼性と整合性を保つために必要。
- PostgreSQLでは、これらの概念がしっかりと実装されており、安全かつ効率的なデータ操作を可能。