ソフトウェア開発会社である K 社は, イントラネットに会議室予約システムを構築し、運用している。
〔会議室予約システムの概要〕
会議室予約システムは,各社員の自席のPC及び会議室に設置されているタブレット端末で利用する。
会議室予約システムには社員番号でログインし、会議室番号,予約日、予約開始時刻,予約終了時刻を指定して会議室予約を行う。 予約開始時刻, 予約終了時刻には30分単位の時刻を入力する。 また, 会議室番号を指定して予約状況を確認したり,人数, 日時を指定して空き会議室を検索したりすることができる。 複数の社員が,同じ会議室に対して重複する日時を指定して予約した場合は, 最も早く実行された予約を予約成功とし, その他は予約失敗とする。
〔会議室予約システムのテーブル〕
会議室予約システムの主要なテーブルのテーブル構造,概要は,図1、表1のとおりである。

〔RDBMS のトランザクション制御〕
会議室予約システムで使用する RDBMS のトランザクションの ISOLATION レベルは READ COMMITTED であり, 行単位でロックをかける。 データ参照時には共有ロックをかけ, 参照終了時に解放する。 データ更新時には専有ロックをかけ, トランザクション終了時に解放する。 専有ロックがかかっている間、他のトランザクションからの対象行の参照, 更新は専有ロックの解放待ちとなる。
〔会議室予約システムでの検索〕
会議室予約システムで空き会議室の検索結果一覧を表示する際に必要な情報を得るために実行する SQL文の例を図2に示す。
なお、図2中のホスト変数の hv1 は予約希望日, hv2 は予約希望開始時刻, hv3 は予約希望終了時刻を表す。

〔会議室予約システムでの予約処理〕
会議室予約システムの予約処理内容は, 図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②の処理を実行することを想定している。る。
なお、後続の予約処理は,先行の予約処理を追い抜くことはないものとする。
(1) ,(2) の検証から, ダブルブッキングとなる理由を次のように結論付けた。
同じ会議室に対して,予約処理の実行が重なった時に,次の二つの条件が成立する場合にダブルブッキングが発生する。
・(r)が重なる。
・(s)が異なる。
〔会議室予約システムの改良案〕
ダブルブッキングを防ぐために図4 表4の “日別予約管理” テーブルを追加し,予約処理内容を図5のように改良することを検討した。
〔会議室予約システムの改良結果〕
図5の⑤〜7の実行時に, ディスク容量不足などのエラーが発生して, 予約処理のトランザクションが中断してしまうと問題が生じることが分かったので, 〔会議室予約システムの改良案〕 は不採用とし, “会議室予約” テーブルを図6のように変更した。
会議室予約を行う予約単位をコマと呼び, 1コマは30分とする。 図6の “会議室予約” テーブルでは,各コマを0時00分から30分間隔で設定する。 予約受付対象の全てのコマはあらかじめ登録しておく。 該当するコマが予約済みか否かを予約済フラグで識別し, 予約済みであれば ‘Y', 予約済みでなければ 'N' とする。 例えば,10時00分〜11時30分を予約済みとする場合, 予約開始時刻が 10 時 00 分, 10時30分, 11時00分の3コマの予約済フラグを 'Y' に更新する。
変更した “会議室予約” テーブルを使用して,予約処理内容を図7のように変更した。
なお、図7中のホスト変数の cnt はコマ数を表す。 また, 図7中のユーザ定義関数について次に示す。
・PERIODSTART 関数は, コマの終了時刻を与えて, コマの開始時刻を求めるユーザ定義関数とする。 例えば, 11時30分を指定した場合, 11 時 00 分が返却される。
・PERIODCOUNT 関数は, 開始時刻と終了時刻を与えて、含まれるコマ数を求めるユーザ定義関数とする。 例えば, 10時00分と11時30分を指定した場合,3が返却される。
・PERIODNEXT 関数は, 指定の時刻とコマ数を与えて、指定の時刻からコマ数だけ後にずらしたコマの開始時刻を求めるユーザ定義関数とする。 例えば, 10時00分とコマ数2を指定した場合, 11時00分が返却される。