ある金融機関が、Azure SQL Database のデータベース設計でデータ整合性を確保する方法を検討している。「口座振替テーブルへの INSERT 時に、送金元の残高が不足している場合は INSERT を拒否し、残高チェックと INSERT を1つの原子的な操作として扱いたい」という要件に最も適した対応はどれか。
- A. ビュー(VIEW):残高と振替を結合したビューを作成して INSERT を仮想テーブル経由で行う
- B. CHECK 制約:INSERT 時に列値の範囲チェックを行うが、他テーブルの値(残高)を参照する複雑なロジックには非対応
- C. アプリケーション層でのチェック:残高をアプリが SELECT してから INSERT を実行するが、並行処理による競合が発生しうる
- D. ACID トランザクション(BEGIN TRANSACTION / COMMIT / ROLLBACK)とロック:残高確認と INSERT を1トランザクションでまとめ、整合性と原子性を保証する
解答と解説を見る
正解: D
リレーショナルデータベースの ACID トランザクション(原子性・一貫性・分離性・耐久性)を活用することが正解である。BEGIN TRANSACTION で開始し、残高確認(SELECT ... WITH UPDLOCK など)と振替 INSERT を同一トランザクション内で実行する。条件を満たさない場合は ROLLBACK し、満たす場合は COMMIT することで、残高チェックと INSERT の原子性が保証される。分離レベルの設定により並行処理の競合も防止できる。アプリケーション層のチェックは SELECT と INSERT の間に別トランザクションが残高を変更する競合状態(race condition)が発生しうる(選択肢Cは不完全)。CHECK 制約は単一行の値を検証できるが他テーブルへの参照を含む複雑な条件は設定できない(選択肢Bは要件不適合)。ビューは通常書き込み操作の整合性制御には使わず、このユースケースに適していない(選択肢Aは不正解)。