9.5. アプリケーションレベルでのデータの一貫性チェック

Postgresではreaderデータをロックしないので、 トランザクションのレベルに関係なく、あるトランザクションで読みこまれた データは、同時に実行されているもう一方のトランザクションによって 書き変えられる可能性があります。つまり、SELECTで 得た行は、その行が返ってきた時(現在のトランザクションが開始されたあとのある時点)にも 存在しているということを意味していません。このトランザクションが開始した後に、 その行は別のトランザクションによって更新、または削除され、コミット されている可能性があります。"今"そのデータが有効であっても、現在 実行中のトランザクションがコミットする、またはロールバックするまでに 変更されたり、削除される可能性があります。

また、各々のトランザクションはデータベースの内容のスナップショットを 参照していて、同時に実行されているトランザクションでも、違った スナップショットを参照している可能性があります。したがって、どちらにしても "今"という概念は少々疑わしいものとなります。これは、クライアント アプリケーションが隔離されている場合は大きな問題ではありませんが、 クライアントがデータベースの外の世界で何かのチャンネルを使用して通信できる場合は 大きな問題となります。

現在存在する行を確実なものとし、同時に起こりうる更新を避けるためには SELECT FOR UPDATE文や、適切な LOCK TABLE文を使用する必要があります。 (SELECT FOR UPDATE文は返ってきたデータのみを 同時に起こる更新から保護し、LOCK TABLEはテーブル 全体を保護します)。これはPostgresに 他の環境からアプリケーションを移植する時に考慮される 必要があります。

Note: Postgresバージョン6.5以前のものでは 読み込みロックを使用しているので、Postgresの バージョン6.5以前のものからバージョンアップする際にも上記の考慮が必要となります。