学習パス 02レッスン 5 / 6

既存システムを安全に変更する

現在の契約を保ちながら変更を導入します。古いクライアント、データ、デプロイの順序を考慮します。

応用11 分レビュー日

発行元 執筆方針

理解度を確認同じリリースでデータベースの列名を変え、アプリも更新します。それでも何が失敗する可能性がありますか?演習に取り組む
同じリリースでデータベースの列名を変え、アプリも更新します。それでも何が失敗する可能性がありますか?

学べること

  • 局所的なコード変更が影響する契約を特定します。
  • 段階的なexpand-and-contractの変更を説明します。
  • コードのロールバックと、データの復旧を区別します。

変更を取り巻く契約を特定する

既存のソフトウェアには、呼び出し元、保存済みデータ、定期実行ジョブ、運用手順があります。編集したいファイルからは見えない依存関係もあります。エージェントが作る変更は、その箇所だけでは正しくても、これらの契約を壊す可能性があります。

実装前に、影響するデータを読み書きするコンポーネントを特定します。ルート、バックグラウンドジョブ、レポート、外部連携を調べてください。他のチームや古いクライアントが、現在の動作に依存していないか確認します。

この依存関係の整理について、根拠を示すようエージェントに依頼します。検索結果は出発点として有用です。ただし、動的な呼び出しや外部の利用側については、責任者による確認が必要な場合があります。

現在の動作を観察できるようにする

文書が不足するモジュールでは、変えてはいけない動作に絞って確認を追加します。それらは現在の契約を示します。既存のすべての動作が望ましいと証明するものではありません。

現在の動作が要件と矛盾する場合は、その矛盾を記録します。テストが記録した動作だからという理由で、セキュリティ上の不具合を残してはいけません。意図した動作と不具合を区別するために必要な判断を得てください。

実際に近い、機密性のないテストデータを使います。古いデータ形式や不完全なレコードが生じ得る箇所では、それらを含めます。新しく作ったデータだけで新スキーマをテストすると、移行の問題を見逃す可能性があります。

バージョン間の移行をレビューする

架空の列名変更として、customer_nameからdisplay_nameへの変更を考えます。すぐに名前を変えると、デプロイ中の古いアプリインスタンスが動かなくなることがあります。一つのpull requestで両方のファイルを更新しても、デプロイが不可分の一操作になるわけではありません。

段階的に進めると、互換性を維持できます。

  1. 古いフィールドを残したまま、新しいフィールドを追加します。
  2. 新しい書き込みで、必要な値の整合性を保つ方法を定めます。
  3. 再開可能な処理で既存レコードの新フィールドを埋めます。
  4. 処理がすべて完了したことと、読み取り側の動作を確認します。
  5. 読み取り側を新しいフィールドへ切り替えます。
  6. 古いフィールドを使うものがなくなってから、古いフィールドを削除します。

具体的な方法は、データベースと書き込みパターンによって変わります。二重書き込みでは、一方が失敗すると不整合が生じる可能性があります。データベースのトランザクションや、別の明示的な同期方法が必要かもしれません。システムの保証を確認せずに、この例を適用しないでください。

Martin Fowlerは、この一般的な移行をparallel change、別名expand-and-contractと説明しています。中心となる考え方は、削除する前に互換性を保って移行することです。

ロールバックとは別に復旧を計画する

コードのロールバックは、以前のアプリバージョンに戻します。データ移行を自動で元に戻すわけではありません。旧バージョンは、新しいデータを扱えない場合があります。破壊的な移行では、コードのロールバックで復元できない情報が失われることがあります。

各段階での復旧操作を特定します。再開可能なデータ補完処理なら、安全に続行できる場合があります。誤った変換には、保存しておいた元データからの修正が必要かもしれません。破壊的な操作には、検証済みの復元手順が必要な場合があります。

復旧の判断を誰が担い、どれだけ時間がかかるか確認してください。「バックアップがある」を、サービスの復旧要件を満たす証拠として扱わないでください。

レビューできる変更に保つ

機能変更と、無関係な整理を分けます。pull requestに互換性の計画、検証結果、削除条件を含めてください。それ以降のロールバックに追加作業が必要になる地点を明示します。

エージェントは、利用側の調査や移行コードの準備を支援できます。それでも、移行と復旧の計画を受け入れる責任者が必要です。最終設計は、安全な変更の一部にすぎません。

演習に取り組む

小さなフィールド変更またはAPI変更を選んでください。バックグラウンドジョブを含め、データを読み書きするすべてのコンポーネントを列挙します。追加だけを行う最初の段階、移行の確認、削除の条件を記述します。ロールバックを妨げる可能性がある段階を特定してください。

ワークシートをダウンロード(Markdown)
理解度を確認 ↑

学習を続ける

出典と参考資料

Taigaの関連資料

← 前のレッスン: AIが生成したコードをレビューする