9.4. シリアライザブル隔離レベル

シリアライザブル隔離レベルは、トランザクションの 隔離としては最も厳密なものです。このレベルではトランザクションが同時にではなく、 次から次へと、あたかも順に実行されているように遂次的なトランザクションの実行を 模倣します。しかし、このレベルを使ったアプリケーションでは、 直列化の失敗のためにトランザクションを再実行しなければならないかもしれなく なる情况を考慮しなければなりません。

トランザクションがシリアライザブル隔離レベルにあるときに SELECT文を実行したら、トランザクションが開始される 前までにコミットされたデータのみを参照し、コミットされていないデータや トランザクション中に別のトランザクションで更新されたデータは参照しません。 (しかし、SELECT文では同じトランザクションで行われた まだコミットされていないデータを参照します)。 SELECT文では、トランザクション内の この問い合わせが行われ始めた状態ではなく、トランザクションそのものの始まった 時の状態のスナップショットで参照するという点でリードコミッティドレベルとは 異っています。

UPDATE文やDELETE文、 SELECT FOR UPDATE文の処理対象行が 同時に実行されている、まだコミットされていないトランザクションによって 更新されている場合、後のトランザクションは前のトランザクションが 終了してコミットされるか、ロールバックされるまで待ちます。 ロールバックされた場合、次に待機しているトランザクションは 該当するデータを更新できます。実行がコミットされた場合は、 シリアライザブルトランザクションは下記のメッセージを表示して ロールバックします。

ERROR:  Can't serialize access due to concurrent update
    
これは、シリアライザブルトランザクションでは、トランザクションが 実行された後に別のトランザクションによって更新されたデータは 更新できないためです。

アプリケーションがこのメッセージを受け取った場合、 現在のトランザクションを中断して、すべてのトランザクションを始めから やり直されなければなりません。2回目では、更新トランザクションはコミットされた 変更含めてをデータベースの最初の状態と見なすので、新しい行をトランザクションの 始点としても、論理的矛盾は起こりません。更新トランザクションのみ 再実行する必要があります。読み込み専用トランザクションではシリアライズの 衝突は決して起こりません。

シリアライザブルトランザクションレベルは、すべてのトランザクションが 一貫したデータベースの状態を参照できることを保障します。 しかし、同時に実行されているトランザクションの更新が、遂次実行の幻想を 維持できなくなり、トランザクションを再実行しなければ ならなくなること、複雑なトランザクションの再実行はかなり 手間がかかるかもしれないことを考慮しなければなりません。したがって、このレベルは、 リードコミッティドでは誤った結果を表示させてしまう可能性がある、 論理的にかなり複雑な問い合わせを実行するときのみに使用することを お勧めします。