
Firestore のトランザクションが守るのは読んだ文書だけ
結論 Firestore のトランザクションが競合として扱うのは、その中で tx.Get した文書だけ。 トランザクションの外で読んだ値、読まずに書いた文書、クエリで「無かった」ことは守らない 悲観 (Standard の既定) と楽観 (Enterprise の既定) で違うのは決着の時点だけで、守る範囲は同じ。 判定に使う値をコールバックの中で読み直せば、同じコードがどちらでも通る 「1 件だけ」を守りたい値はドキュメント ID にして名指しで読む。件数を数える判定は、エミュレータでも条件次第で 2 件できた SDK はコールバックの中での生のクライアントの書き込みも、外側の ctx で張った RunTransaction も止めない。どちらもトランザクションの外で確定する 複数の文書を「全部か、無しか」で書くなら RunTransaction。BulkWriter はアトミックでない 以下は cloud.google.com/go/firestore v1.26.0 / Firestore エミュレータ v1.22.0 / Go 1.26.4 で実測した。 エミュレータは --database-edition=standard と --database-edition=enterprise の 2 つを立てた。 本番の Firestore では試していない。 前提: 競合として扱うのは、トランザクション内で読んだ文書だけ 公式ドキュメントは、並行制御の 2 つの方式をどちらも「読んだ文書」で説明している ( Data contention in transactions )。 悲観: “transactions place locks on the documents they read” 楽観: 読んだ文書を追跡し、“only if none of those documents changed” のときだけ書き込みを確定する 読んでいない文書はロックも照合もされない。 書くだけの文書、トランザクションの外で読んだ値、クエリの結果に入らなかった文書は、守る対象に入らない。 以下の節は、どれもこの 1 点から出てくる。 ...



