いいえ、ドキュメントは正しくありません。トランザクションを単独で使用しても、この問題は回避できません。例外が発生した場合にトランザクション全体がロールバックされることを保証するだけであり、データベースに一貫性のない状態が保持されることはありません。
この問題を回避するには、トランザクション内でテーブルをロックする必要があります。これは、すべてのロックがトランザクションの終了時に解放されるためです。何かのようなもの:
BEGIN;
LOCK TABLE mytbl IN SHARE MODE;
-- do your find_or_create here
COMMIT;
しかし、それはすべての魔法の治療法ではありません. これはパフォーマンスの問題になる可能性があり、デッドロック(他のトランザクションが既にロックしているリソースを相互にロックしようとする並行トランザクション) が発生する可能性があります。PostgreSQL はそのような状態を検出し、競合するトランザクションの 1 つを除くすべてをキャンセルします。失敗した場合に操作を再試行する準備をしておく必要があります。
ロックに関する PostgreSQL のマニュアル。
並行性があまりない場合は、問題を無視することもできます。タイムスロットは非常に小さいため、実際に発生することはほとんどありません。害を及ぼさない重複キー違反エラーをキャッチした場合は、これもカバーしています。