サブトランザクションはトランザクション内で開始され、大きなトランザクションを小さな単位に分割できます。 サブトランザクションは、親トランザクションに影響を与えることなくコミットまたは中断できるため、親トランザクションを継続できます。 これにより、アプリケーションの開発パターンによくあるエラーの処理が容易になります。 この用語は、しばしばsubxactと省略されます。
サブトランザクションはSAVEPOINT
コマンドを使用して明示的に開始できますが、PL/pgSQLのEXCEPTION
句などの他の方法でも開始できます。
PL/PythonとPL/Tclも明示的なサブトランザクションをサポートしています。
サブトランザクションは他のサブトランザクションから開始することもできます。
トップレベルのトランザクションとその子トランザクションは階層またはツリーを形成するため、メイントランザクションをトップレベルのトランザクションと呼びます。
サブトランザクションに仮想トランザクションID以外のIDが割り当てられた場合、そのトランザクションIDは「subxid」と呼ばれます。 読取専用のサブトランザクションにはsubxidは割り当てられませんが、書込みを試みると割り当てられます。 これにより、トップレベルのトランザクションを含むすべての親サブトランザクションに、非仮想トランザクションIDが割り当てられます。 親xidは常に子subxidのいずれよりも小さいことが保証されます。
各subxidの直接の親xidはpg_subtrans
ディレクトリに記録されます。
トップレベルのxidには親がないのでエントリは記録されません。
読み取り専用のサブトランザクションにもエントリは記録されません。
サブトランザクションがコミットされると、その子サブトランザクションのすべての子サブトランザクションのxidがコミットされたものとみなされます。 サブトランザクションが中断された場合、その子サブトランザクションすべても中断されたものとみなされます。
xidを持つトップレベルトランザクションがコミットすると、そのサブトランザクションの子サブトランザクションもすべてpg_xact
サブディレクトリに永続的にコミット済みとして記録されます。
トップレベルトランザクションが中断された場合、そのサブトランザクションは、たとえサブトランザクションがコミットされていたとしても中断されます。
トランザクションがオープンしたサブトランザクション数が多いほど(ロールバックや解放されない)、トランザクション制御のオーバーヘッドが大きくなります。
各バックエンドで最大64個のオープンしたサブトランザクションが共有メモリにキャッシュされます。
その後、pg_subtrans
内のサブxidエントリの追加検索により、ストレージI/Oオーバーヘッドが大幅に増加します。