GCP の 409 エラー:原因と解決策
冒頭まとめ GCP の 409 Conflict は、2つの異なる区分に対応します。エラー区分の定義ファイルを見ると、1つは作ろうとしたものが既に存在する場合、もう1つは同時実行の衝突で処理が中断された場合です。 この2つは、対処が正反対です。 前者は、状態が既に望みどおりになっている可能性があります。作成の操作を繰り返す自動化では、2回目以降は必ずこのエラーになります。異常として止めるのではなく、既にあるものを使う分岐を持つのが正しい作りです。 後者は、他の処理と衝突しました。定義には、この区分をどう扱うべきかが明示されています。実装する側への指針として、失敗した呼び出しだけを再試行してよいのが 503 の区分、上位の処理からやり直すべきなのがこの区分、系の状態が明示的に直されるまで再試行すべきでないのが 400 の区分、と3つが並べて説明されています。例として挙げられているのは、値を確認してから書き換える処理が失敗した場合で、読み取りから書き込みまでの一連の流れをやり直すべきだ、とされています。 つまり、同じ要求をそのまま送り直すのは、この区分に対しては誤った対処です。読み取りからやり直す必要があります。 したがって、409 を見たときに最初に読むべきは status の値です。ここで、待つのか、既存を使うのか、処理全体をやり直すのかが決まります。 エラーの概要 応答の形は他のエラーと共通です。既に存在する場合は次のようになります。 { "error": { "code": 409, "message": "The resource 'projects/my-project/zones/asia-northeast1-a/instances/my-vm' already exists", "status": "ALREADY_EXISTS" } } message に、既に存在する対象の完全な名前が入ります。自分が作ろうとした名前と同じであることを確認できます。 同時実行の衝突の場合は、区分名が変わります。 { "error": { "code": 409, "message": "Aborted due to cross-transaction contention.", "status": "ABORTED" } } こちらは対象の名前ではなく、衝突の理由が書かれます。同時に走っている処理があった、という趣旨の文言です。 コマンド行の道具からは、簡潔な形で表示されます。作成の操作を繰り返した場合、既に存在する旨がそのまま出ます。 まず最初に:status で3方向に振り分ける 第一に、status の値を読みます。ALREADY_EXISTS なら既に存在します。ABORTED なら同時実行の衝突です。 第二に、ALREADY_EXISTS であれば、既存のものが自分の望む状態かを確認します。同じ設定であれば、そのまま使えます。違えば、更新の操作に切り替えます。 第三に、ABORTED であれば、読み取りからやり直します。同じ要求の送り直しではありません。 第四に、FAILED_PRECONDITION が返っている場合は 409 ではなく 400 です。状態が整うまで待つ必要があります(GCP の 400 の記事)。混同しやすい3つですが、区分名で確実に分かれます。 ...
{
"error": {
"code": 409,