よろずやIT
プログラミング

レースコンディション(競合状態)とは?同時アクセスが引き起こす、見えないバグ

執筆・監修:よろずやIT編集部|編集方針を見る

結論:まずここだけ読めばOK

詳しい手順・原因は、この下で解説しています。

プログラミングのイラスト

レースコンディションとは何か

レースコンディション(競合状態)とは、複数の処理が、同じデータやリソースにほぼ同時にアクセスした際、実行される順序によって結果が変わってしまう現象のことです。「レース(競争)」という名前の通り、どちらの処理が先にゴールするかによって、最終的な結果が変わってしまうイメージです。

図で見る、典型的な発生パターン

言葉だけでは分かりにくいので、よく紹介される銀行口座の例で確認してみましょう。

レースコンディションの発生例を示す図解

残高が1万円しかない口座から、2つの出金処理がほぼ同時に実行されたとします。それぞれの処理は「残高を確認 → 問題なければ出金する」という手順を踏みますが、片方の処理が残高を確認した直後、まだ出金を完了する前に、もう片方の処理も同じ残高を確認してしまうと、両方とも「まだ1万円ある」と判断して出金を実行してしまいます。結果として、実際には1万円しかないはずの口座から、合計2万円が引き出されてしまうことになります。

なぜテストでは見つかりにくいのか

レースコンディションが厄介なのは、問題が表面化するために、非常に狭いタイミングの一致が必要だという点です。開発中の環境では、複数の処理が同時に集中する状況が起こりにくく、たまたま順番通りに動いてしまうため、バグが存在していても気づかれずに残ってしまいます。本番環境でアクセスが増え、同時に処理が走る頻度が上がって初めて、稀に不可解な不具合として表面化する、というパターンが典型的です。

「確認」と「実行」の間に隙がある:TOCTOU

先ほどの銀行口座の例のように、「何かを確認した時点」と「実際にそれをもとに操作を実行する時点」の間に状況が変わってしまう現象は、特に「TOCTOU(Time of Check to Time of Use)」と呼ばれる代表的なパターンです。OWASP(セキュリティに関する国際的な非営利団体)の資料でも、この種の問題が取り上げられており、悪用されるとシステムの想定外の挙動を引き起こす、セキュリティ上のリスクにもなり得るとされています。

実務で起こりやすい場面

いずれも、「確認してから実行するまでの、ごくわずかな時間差」を突かれることで起こります。

基本的な対策の考え方

まとめると

レースコンディションは、複数の処理が同時に動く場面で静かに潜んでいる、見えにくいバグです。開発中に再現しないからといって「存在しない」とは限らない、という点を意識しておくだけでも、設計時の注意深さが変わってきます。在庫・予約・決済など、「同時に複数人が操作しうる」機能を作る際は、特に意識しておきたい考え方です。

参考

OWASP Top 10:2021 - Next Steps(OWASP)

PR【中古】 1からはじめるITアーキテクチャー構築入門 システム設計の基礎から実践まで/二上哲也(著者),田端真由美(著者)

【中古】 1からはじめるITアーキテクチャー構築入門 システム設計の基礎から実践まで/二上哲也(著者),田端真由美(著者)

¥2,480

楽天で見る
SHAREXLINEはてブ

よくある質問

Q.レースコンディションは、なぜテストで見つけにくいのですか?

A.問題が表面化するには、複数の処理がごく短い時間差でぶつかるという、特定のタイミングが必要だからです。開発環境やテスト環境では処理が同時に集中しにくく、たまたま順番通りに動いてしまうため、バグが隠れたまま気づかれにくくなります。

Q.『TOCTOU』とは何ですか?

A.「Time of Check to Time of Use」の略で、レースコンディションの代表的なパターンの1つです。何かを確認した時点(Check)と、実際にそれを使う時点(Use)の間に、状況が変わってしまうことで問題が起こる現象を指します。

Q.個人開発の小さなアプリでも、意識する必要がありますか?

A.利用者が少なく、同時アクセスがほぼ起こらない個人アプリであれば、優先度は下がります。ただし、在庫管理・予約・決済のように『同時に複数人が操作する可能性がある』機能を含む場合は、規模の大小にかかわらず意識しておく価値があります。

関連記事

最新のIT関連書籍 トップ10

PR / 楽天市場の売れ筋ランキングを定期的に取得しています。価格は変動する場合があるため、購入前に各ストアでご確認ください。