DBデータベーススペシャリスト試験 午後Ⅰ

平成26年度春期 データベーススペシャリスト 午後Ⅰ 問2

事例を読んで設問の答えを考えてから、解説のポイントとIPA公式の解答例・採点講評で確認しましょう。

問題

問2 データベースアクセスの同時実行制御に関する次の記述を読んで,設問1~3に答えよ。 ソフトウェア開発会社であるK社は,イントラネットに会議室予約システムを構築し,運用している。 〔会議室予約システムの概要〕 会議室予約システムは,各社員の自席のPC及び会議室に設置されているタブレット端末で利用する。 会議室予約システムには社員番号でログインし,会議室番号,予約日,予約開始時刻,予約終了時刻を指定して会議室予約を行う。予約開始時刻,予約終了時刻には30分単位の時刻を入力する。また,会議室番号を指定して予約状況を確認したり,人数,日時を指定して空き会議室を検索したりすることができる。複数の社員が,同じ会議室に対して重複する日時を指定して予約した場合は,最も早く実行された予約を予約成功とし,その他は予約失敗とする。 〔会議室予約システムのテーブル〕 会議室予約システムの主要なテーブルのテーブル構造,概要は,図1,表1のとおりである。 図1 主要なテーブルのテーブル構造(一部省略) 表1 主要なテーブルの概要 〔RDBMSのトランザクション制御〕 会議室予約システムで使用するRDBMSのトランザクションのISOLATIONレベルはREAD COMMITTEDであり,行単位でロックをかける。データ参照時には共有ロックをかけ,参照終了時に解放する。データ更新時には専有ロックをかけ,トランザクション終了時に解放する。専有ロックがかかっている間,他のトランザクションからの対象行の参照,更新は専有ロックの解放待ちとなる。 〔会議室予約システムでの検索〕 会議室予約システムで空き会議室の検索結果一覧を表示する際に必要な情報を得るために実行するSQL文の例を図2に示す。 図2 検索で実行するSQL文の例 なお,図2中のホスト変数のhv1は予約希望日,hv2は予約希望開始時刻,hv3は予約希望終了時刻を表す。 〔会議室予約システムでの予約処理〕 会議室予約システムの予約処理内容は,図3のとおりである。 図3 予約処理内容 なお,図3中のホスト変数のhv1は指定予約日,hv2は指定予約開始時刻,hv3は指定予約終了時刻,hv4は指定会議室番号,hv5は予約者の社員番号を表す(以降の図5,図7でも同様とする)。 〔会議室予約システムでのダブルブッキングの検証〕 会議室予約システムにおいてダブルブッキングが発生した。K社ではその原因を突き止めるために当日の状況を基に,次の例を用いて図3の予約処理内容の検証を行った。 (例) ・会議室123に対する2014年4月1日の予約を行う。その日の予約は終日入っていなかった。 ・Aさん,Bさん,Cさん,Dさん,Eさんの5人が,それぞれ次の時間帯を指定した。  Aさん:11時00分~12時00分  Bさん:11時00分~13時00分  Cさん:11時30分~13時00分  Dさん:9時00分~11時00分  Eさん:8時00分~18時00分 (検証) 5人の予約処理の実行が重ならない場合と,重なった場合について,それぞれ(1),(2)で検証した。 (1)Aさん,Bさん,Cさん,Dさん,Eさんの順番で,予約処理の実行が重ならない場合の結果を検証して,表2を作成した。 (2)Aさん,Bさん,Cさん,Dさん,Eさんのうち,2人ずつの全ての組合せに対して,先行,後続を入れ替えて,予約処理の実行が重なった場合の結果を検証して,表3を作成した。表3では,先行の予約処理が図3①の処理を実行した後に,後続の予約処理が図3①の処理を実行,その後に先行の予約処理が図3②の処理を実行することを想定している。 なお,後続の予約処理は,先行の予約処理を追い抜くことはないものとする。 表2 予約処理の実行が重ならない場合の結果 表3 2人の予約処理の実行が重なった場合の後続の結果 (1),(2)の検証から,ダブルブッキングとなる理由を次のように結論付けた。 同じ会議室に対して,予約処理の実行が重なった時に,次の二つの条件が成立する場合にダブルブッキングが発生する。 ・[r]が重なる。 ・[s]が異なる。 〔会議室予約システムの改良案〕 ダブルブッキングを防ぐために図4,表4の“日別予約管理”テーブルを追加し,予約処理内容を図5のように改良することを検討した。 図4 追加する“日別予約管理”テーブルのテーブル構造 表4 追加する“日別予約管理”テーブルの概要 図5 予約処理内容改良案 〔会議室予約システムの改良結果〕 図5の⑤~⑦の実行時に,ディスク容量不足などのエラーが発生して,予約処理のトランザクションが中断してしまうと問題が生じることが分かったので,〔会議室予約システムの改良案〕は不採用とし,“会議室予約”テーブルを図6のように変更した。 図6 変更した“会議室予約”テーブルのテーブル構造 会議室予約を行う予約単位をコマと呼び,1コマは30分とする。図6の“会議室予約”テーブルでは,各コマを0時00分から30分間隔で設定する。予約受付対象の全てのコマはあらかじめ登録しておく。該当するコマが予約済みか否かを予約済フラグで識別し,予約済みであれば‘Y’,予約済みでなければ‘N’とする。例えば,10時00分~11時30分を予約済みとする場合,予約開始時刻が10時00分,10時30分,11時00分の3コマの予約済フラグを‘Y’に更新する。 変更した“会議室予約”テーブルを使用して,予約処理内容を図7のように変更した。 図7 予約処理内容の改良結果 なお,図7中のホスト変数のcntはコマ数を表す。また,図7中のユーザ定義関数について次に示す。 ・PERIODSTART関数は,コマの終了時刻を与えて,コマの開始時刻を求めるユーザ定義関数とする。例えば,11時30分を指定した場合,11時00分が返却される。 ・PERIODCOUNT関数は,開始時刻と終了時刻を与えて,含まれるコマ数を求めるユーザ定義関数とする。例えば,10時00分と11時30分を指定した場合,3が返却される。 ・PERIODNEXT関数は,指定の時刻とコマ数を与えて,指定の時刻からコマ数だけ後にずらしたコマの開始時刻を求めるユーザ定義関数とする。例えば,10時00分とコマ数2を指定した場合,11時00分が返却される。 設問1 会議室予約システムについて,(1)~(4)に答えよ。 (1)図2中のSQL文の[a]~[c]に入れる適切な字句を答えよ。 (2)図3中の②は,行が挿入できないことでダブルブッキングとならないように制御している。その制御で行が挿入できない理由を30字以内で述べよ。 (3)表2中の[d]~[i]及び表3中の[j]~[q]に入れる予約成否,失敗検知箇所を答えよ。 なお,予約成否は,表2中の注記の記号で答えること。失敗検知箇所は,予約成否が×の場合に予約失敗を検知した箇所を図3中の番号で答えること。×でない場合は空欄のままとすること。 (4)ダブルブッキングとなる条件の[r],[s]に入れる適切な字句を答えよ。 設問2 〔会議室予約システムの改良案〕について,(1)~(3)に答えよ。 (1)同じ日に,同じ会議室に対して予約が集中する状況を想定すると,図5中の②でコミットを行わない場合,スループットが低下する。その原因となる処理を図5中の番号で答えよ。また,原因を25字以内で述べよ。 (2)図5中の④において,⑧に進む処理は,速やかに予約失敗を検知するために行っている。この処理はどのような状況を想定して行っているか。20字以内で述べよ。 (3)〔会議室予約システムの改良結果〕で述べている〔会議室予約システムの改良案〕で生じる問題について,どのテーブルがどのような状態になるかを40字以内で述べよ。また,それによって引き起こされる問題を30字以内で述べよ。 設問3 〔会議室予約システムの改良結果〕について,(1),(2)に答えよ。 (1)図7中の[t]に入れる適切な字句を答えよ。 (2)図7中の②において,更新行がなくて予約失敗となるのはどのような状況か。40字以内で述べよ。
図1 主要なテーブルのテーブル構造(一部省略)。社員,会議室,会議室予約の主要なテーブル構造を示す図。各テーブルの属性と主キー項目が示されている。
図1 主要なテーブルのテーブル構造(一部省略)。社員,会議室,会議室予約の主要なテーブル構造を示す図。各テーブルの属性と主キー項目が示されている。
表1 主要なテーブルの概要。社員,会議室,会議室予約の各テーブルについて,管理対象と一意識別方法などの概要を整理した表。
表1 主要なテーブルの概要。社員,会議室,会議室予約の各テーブルについて,管理対象と一意識別方法などの概要を整理した表。
図2 検索で実行するSQL文の例。会議室と会議室予約を対象に,指定日と希望時間帯に重なる予約の有無を検索するSQL文の例。
図2 検索で実行するSQL文の例。会議室と会議室予約を対象に,指定日と希望時間帯に重なる予約の有無を検索するSQL文の例。
図3 予約処理内容。重複予約をSELECTで確認し,重複がなければINSERTし,予約成否を通知する予約処理の流れ。
図3 予約処理内容。重複予約をSELECTで確認し,重複がなければINSERTし,予約成否を通知する予約処理の流れ。
表2 予約処理の実行が重ならない場合の結果。AさんからEさんまで順番に予約処理を実行した場合の予約成否と失敗検知箇所を示す表。
表2 予約処理の実行が重ならない場合の結果。AさんからEさんまで順番に予約処理を実行した場合の予約成否と失敗検知箇所を示す表。
表3 2人の予約処理の実行が重なった場合の後続の結果。5人の予約処理について,先行と後続を入れ替えた場合の後続処理の予約成否と失敗検知箇所を示す表。
表3 2人の予約処理の実行が重なった場合の後続の結果。5人の予約処理について,先行と後続を入れ替えた場合の後続処理の予約成否と失敗検知箇所を示す表。
図4 追加する“日別予約管理”テーブルのテーブル構造。会議室番号,予約日,予約処理中フラグを属性とする日別予約管理テーブルの構造。
図4 追加する“日別予約管理”テーブルのテーブル構造。会議室番号,予約日,予約処理中フラグを属性とする日別予約管理テーブルの構造。
表4 追加する“日別予約管理”テーブルの概要。日別予約管理テーブルの用途,予約処理中フラグの意味,事前登録される初期値を説明した表。
表4 追加する“日別予約管理”テーブルの概要。日別予約管理テーブルの用途,予約処理中フラグの意味,事前登録される初期値を説明した表。
図5 予約処理内容改良案。日別予約管理テーブルのフラグ更新,重複確認,予約登録,フラグ復元を行う改良後の予約処理手順。
図5 予約処理内容改良案。日別予約管理テーブルのフラグ更新,重複確認,予約登録,フラグ復元を行う改良後の予約処理手順。
図6 変更した“会議室予約”テーブルのテーブル構造。会議室予約テーブルに予約済フラグを追加した変更後のテーブル構造。
図6 変更した“会議室予約”テーブルのテーブル構造。会議室予約テーブルに予約済フラグを追加した変更後のテーブル構造。
図7 予約処理内容の改良結果。予約コマの空き数を確認し,コマごとに予約済フラグを更新する改良後の予約処理手順。
図7 予約処理内容の改良結果。予約コマの空き数を確認し,コマごとに予約済フラグを更新する改良後の予約処理手順。
解き方のヒントを見る

同時実行時の整合性を考える視点

複数の処理が重なる場面では、個々の操作だけでなく、予約から確定までの流れを一つのまとまりとして捉え、途中状態が他の処理にどう影響するかを確認します。順序と境界に注目します。

この問題で問われていること

確認の中心は、同じ資源を扱う処理同士がどの時点で関わり、処理の途中で見える状態と最終的に確定する状態の関係が保たれているかを整理することです。この一点に絞って見直します。

視点

処理を個別の命令ではなく、開始から確定までの単位として眺め、他の処理との重なりによって状態の見え方や確定順序が変わり得る箇所を整理します。

確認ポイント

  • 対象となる共有資源と、それを参照・更新する処理の範囲を対応づける
  • 処理の途中と確定後で、他の処理から見える状態を区別する
  • 重なりが起きた場合に、どの順序や境界を基準に整合性を判断するか確認する
正解と解説を見る

解説

会議室予約を題材に、時間帯の重複を判定するSQL、主キー制約による競合検知、ロックの保持時間、予約単位をコマに分割した排他制御を問う問題です。

問題の全体像

K社の会議室予約システムでは、同じ会議室の重複時間帯を予約できないようにする必要がある。元の処理は、重複予約をSELECTで確認してからINSERTするため、同時実行時には両方が空きと判断してダブルブッキングが起こり得る。設問1ではSQLと競合結果、設問2では日別管理テーブルによる改善案のロックや障害時の問題、設問3では予約枠ごとの更新による改良結果を確認する。出題趣旨では、SQL設計に加え、トランザクション制御と排他制御を理解して同時実行性を設計する力を評価している。

設問1(1)

公式解答例は、[a]NOT EXISTS、[b]<、[c]>としている。空き会議室の検索なので、対象会議室について重複する予約行が存在しないことをNOT EXISTSで表す。時間帯は、既存予約の開始時刻が希望終了時刻より前、かつ既存予約の終了時刻が希望開始時刻より後である場合に重なるため、比較演算子はそれぞれ<と>になる。境界で一方の終了時刻と他方の開始時刻が一致する場合は重複とは扱わない。

設問1(2)

公式解答例は「主キーの値が重複するから」などとしている。図1の会議室予約の主キーは会議室番号、予約日、予約開始時刻で構成される。同じ開始時刻の予約を同時に登録しようとすると、先に登録された行と主キーが重複するため、後続のINSERTは行を挿入できない。答案では、主キー重複または三つの主キー項目が同じ行の存在を30字以内で示せばよい。

設問1(3)

実行が重ならない場合、公式解答例は[d]×・[e]①、[f]○・[g]空欄、[h]×・[i]①としている。Aの予約後、BとCは既存予約と時間帯が重なるため図3①のSELECTで失敗する。DはAと終了・開始が接するだけなので成功し、Eは既存予約と重なるため①で失敗する。同時実行では、公式解答例は[j]×・[k]②、[l]△・[m]空欄、[n]○・[o]空欄、[p]△・[q]空欄です。AとBは開始時刻が同じなので後続のINSERTが主キー重複を検知する。一方、AとC、AとEは時間帯が重なるが開始時刻が異なるため、両方のINSERTが通りダブルブッキングとなる。AとDは時間帯が重ならないため、両方とも成功する。

設問1(4)

公式解答例は[r]時間帯、[s]予約開始時刻としている。ダブルブッキングには、二つの予約の時間帯が重なることが必要です。しかし、開始時刻が同じなら主キー重複で後続処理が失敗するため、両方が登録されるには予約開始時刻が異なる必要がある。したがって、時間帯が重なり、予約開始時刻が異なる場合が条件になる。

設問2(1)(処理番号)

公式解答例は処理番号①としている。①では、日別予約管理の予約処理中フラグをNからYへ更新する。この更新による専有ロックはトランザクション終了まで保持されるため、同じ日・同じ会議室への予約が集中すると、後続処理が①の行のロック解放を待つことになる。

設問2(1)(原因)

公式解答例は「多数の専有ロックの解放待ちが発生する」としている。図5②でコミットしなければ、①で取得した専有ロックを保持したまま③以降の処理を続ける。その間、同じ日・同じ会議室を処理する多数のトランザクションがロック待ちとなり、同時に処理できる件数が減少する。

設問2(2)

公式解答例は「予約対象に予約が入っている状況」としている。図5④では、①の更新に失敗して予約処理中フラグを取得できなくても、③のSELECTで対象時間帯に既存予約があることを確認できた場合を想定する。この場合はロック取得を繰り返さず、既に予約済みなので⑧へ進んで速やかに失敗を通知する。

設問2(3)(状態)

公式解答例は、「日別予約管理」テーブルの予約処理中フラグがYのままとなる状態としている。図5②のコミット後に⑤~⑦で障害が起きると、⑥のNへの更新や⑦のコミットまで到達できない。一方、②は既に完了しているため、そのテーブルのYは元に戻らず残る。

設問2(3)(問題)

公式解答例は、その日付・その会議室を誰も予約できなくなるとしている。予約処理中フラグがYのままだと、後続の予約処理は日別予約管理の行をNからYへ更新できない。結果として、実際には予約処理中でないのに、その日・会議室の予約受付が停止する。

設問3(1)

公式解答例は[t]COUNT(*)としている。図7①のSELECTは、指定された会議室・日付・時間範囲について、予約済フラグがNのコマを数える。GROUP BYで会議室ごとにまとめ、空きコマ数が予約に必要なコマ数PERIODCOUNT(:hv2、:hv3)と一致する場合に、範囲内の全コマが空いていると判断できる。

設問3(2)

公式解答例は、①の終了後、②の終了までの間に他の予約処理が範囲内のコマへ予約を入れた状況としている。①では全コマが空きと確認できても、②のUPDATEをコマ数分繰り返す間に別トランザクションが先に一部の予約済フラグをYへ変更することがある。そのコマはWHERE句の予約済フラグ=Nに一致せず更新行がなくなり、予約失敗としてロールバックされる。

学習のポイント

SQL条件だけでなく、トランザクションの順序とロックの解放時点まで追跡する力を養う。

出典:独立行政法人 情報処理推進機構(IPA)平成26年度春期 データベーススペシャリスト試験 午後Ⅰ 問2(公式資料:問題冊子(PDF) / 解答例 / 採点講評)

関連する過去問一覧

IPA Advancedは非公式の学習サイトです。解説にはAIによる補助生成を含む場合があります。公式の問題冊子・解答例・採点講評を優先し、誤りは確認後に訂正します。運営・編集方針