【きょうごうじょうたい】
競合状態(レースコンディション) とは?
最終更新:
💡 別々に正しい処理でも、交ざると結果が崩れる
複数の処理の進み方やタイミングによって、本来守るべき結果が崩れる問題。共有値を読んでから更新する間に別の処理が入ると、加算の消失や二重販売などが起きる。守る範囲全体を一つの操作として扱うなど、処理に合った対策が必要。
📌 このページのポイント
- 読み取り・判断・更新の間に別の処理が入ると問題になる
- 同時の一瞬だけでなく、処理が交ざる順序が重要
- ロックや不可分な操作は、守る範囲と参加する処理をそろえる
- DBでは条件付き更新・行ロック・分離レベルなどを目的に合わせて選ぶ
どうして足し算の結果が変わるの?
共有カウンターが0で、AとBがそれぞれ1を足す例を考えよう。両方が先に0を読み、それぞれ1を作って書くと、最後は1になる。本来は2になってほしいのに、1回分が失われるんだ。
まったく同じ瞬間に動くと起きる?
同じ瞬間に実行する必要はないよ。Aが読んだ後、書く前にBも読む、というように処理が交ざることが問題なんだ。実行の順序が違えば、期待した結果になる場合もあるね。
Webサービスでも起きる?
在庫1個をAとBが別々に確認し、どちらも購入を受け付けてしまう例があるよ。チェックと在庫の更新を別々に行うと、その間に他の注文が入れる。確認と更新を守る仕組みが必要なんだ。
ロックを付ければ解決できる?
テストで見つけられる?
タイミングによって再現しない場合もあるよ。処理の交ざる順序を考えて試すことが大切。ThreadSanitizerはデータ競合の検出に使えるけれど、在庫のような業務上の競合まで全部見つける道具ではないんだ。
まとめ:ざっくりこれだけ覚えればOK!
「競合状態」って出てきたら「処理のタイミングが交ざって、結果が崩れる問題」と思えばだいたいOK!
📖 おまけ:英語の意味
「Race Condition」 = 競合状態
💬 Raceは競争。複数の処理が進む順序やタイミングによって、共有する結果が変わることを表すよ。