「資格試験/情報処理技術者試験/情報セキュリティスペシャリスト/過去問2013年春午後2/問1設問3-1」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
* 設問3 予約管理機能の不具合について(1)~(4)に答えよ。
(1) 表7を完成させるために、【h】~【l】に入れる適切な字句又は数字を答えよ。
>【h】:42
>【i】:α
>【j】:60
>【k】:β
>【l】:60
* 解説
表7の穴埋め問題です
まず本文抜粋
不具合の発見を受けて、図5及び図6について、顧客αと顧客βがそれぞれのブラウザから操作を行うことを想定して、ソースコードレビューを行った。
その結果、顧客αと顧客βが、画面2で空き状態であった&bold(){&color(red){同一の予約枠をほぼ同時に選択した場合}}、表7に示す順序で各処理が完了すると、&bold(){&color(red){顧客αの仮予約がデータベースに反映されない}}ことが確認できた。
ざっくり要約すると「αβが同時に同一の予約枠をほぼ同時に選択した場合に、αの仮予約がデータベースに反映されない」となりますが、原因は簡単「&bold(){αの仮予約の次の瞬間に、βも仮予約したからαの仮予約が消えた}」と考えられます。
** 図5 サーブレット"WakuClick" 抜粋
#divclass(blackdiv){{
1~39: (管理人省略)
40: (4) (4) // 選択された予約枠の予約状況を参照する
41: (4) (4) psSel.setString(1, rsvDate); psSel.setString(2, rsvTime); psSetl.setString(3, rsvBiyoshi);
42: (4) (4) ResultSet rs = psSel.executeQuery();
43: (4) (4) rs.next(); &bold(){&color(red){← [表7手順1 予約枠の予約状況を参照!]}}
44: (4) (4) long lastDateTime = rs.getLong("LastUpdate");
45: (4) (4) // 現在の時刻を取得する
46: (4) (4) long nowDateTime = new Date().getTime();
47: (4) (4) // 既に仮予約状態であった場合、仮予約の最終更新日時を確認し、TIMEOUT_KARI経過後なら空きにする
48: (4) (4) int rsvStatus = rs.getInt("Status");
49: (4) (4) if (rsvStatus == RSV_KARI) {
50: (4) (4) (4) if ((nowDateTime - lastDateTime) > TIMEOUT_KARI) {
51: (4) (4) (4) (4) rsvStatus = RSV_AKI;
52: (4) (4) (4) }
53: (4) (4) }
54: (4) (4) // 予約状況が空きであることを確認し、仮予約処理を行う
55: (4) (4) if (rsvStatus == RSV_AKI) {
56: (4) (4) (4) psUp.setInt(1, RSV_KARI); psUp.setString(2, loginUserID); psUp.setString(3, "");
57: (4) (4) (4) psUp.setString(4, ""); psUp.setLong(5, nowDateTime);
58: (4) (4) (4) psUp.setString(6, rsvDate);
59: (4) (4) (4) psUp.setString(7, rsvTime); psUp.setString(8, rsvBiyoshi);
60: (4) (4) (4) psUp.executeUpdate(); &bold(){&color(red){← [仮予約の更新を行うところ]}}
61: (4) (4) (4) (省略)[図6の処理を引き継ぐために、選択した予約枠の情報をサーブレットのセッション情報に保存する]
62: (4) (4) (4) (省略)[画面3のHTML出力を行う]
63~ (管理人省略)
}}
** 図5 サーブレット"WakuClick" 抜粋終わり
肝になるのは、42行目の&bold(){&color(red){[予約枠の予約状況を参照!]}}と60行目の&bold(){&color(red){[仮予約の更新を行うところ]}}です。
** 表7 仮予約が無効になる処理の順序
|順序|対象の顧客|処理|
|1|α|図5の42行目|
|2|β|図5の【 h 】行目|
|3|【 i 】|図5の【 j 】行目|
|4|【 k 】|図5の【 l 】行目|
[[設問に戻る>資格試験/情報処理技術者試験/情報セキュリティスペシャリスト/過去問2013年春午後2/問1#設問]]
* 設問3 予約管理機能の不具合について(1)~(4)に答えよ。
(1) 表7を完成させるために、【h】~【l】に入れる適切な字句又は数字を答えよ。
>【h】:42
>【i】:α
>【j】:60
>【k】:β
>【l】:60
* 解説
表7の穴埋め問題です
まず本文抜粋
不具合の発見を受けて、図5及び図6について、顧客αと顧客βがそれぞれのブラウザから操作を行うことを想定して、ソースコードレビューを行った。
その結果、顧客αと顧客βが、画面2で空き状態であった&bold(){&color(red){同一の予約枠をほぼ同時に選択した場合}}、表7に示す順序で各処理が完了すると、&bold(){&color(red){顧客αの仮予約がデータベースに反映されない}}ことが確認できた。
ざっくり要約すると「αβが同時に同一の予約枠をほぼ同時に選択した場合に、αの仮予約がデータベースに反映されない」となりますが、原因は簡単「&bold(){αの仮予約の次の瞬間に、βも仮予約したからαの仮予約が消えた}」と考えられます。
** 図5 サーブレット"WakuClick" 抜粋
#divclass(blackdiv){{
1~39: (管理人省略)
40: (4) (4) // 選択された予約枠の予約状況を参照する
41: (4) (4) psSel.setString(1, rsvDate); psSel.setString(2, rsvTime); psSetl.setString(3, rsvBiyoshi);
42: (4) (4) ResultSet rs = psSel.executeQuery();
43: (4) (4) rs.next(); &bold(){&color(red){← [表7手順1 予約枠の予約状況を参照!]}}
44: (4) (4) long lastDateTime = rs.getLong("LastUpdate");
45: (4) (4) // 現在の時刻を取得する
46: (4) (4) long nowDateTime = new Date().getTime();
47: (4) (4) // 既に仮予約状態であった場合、仮予約の最終更新日時を確認し、TIMEOUT_KARI経過後なら空きにする
48: (4) (4) int rsvStatus = rs.getInt("Status");
49: (4) (4) if (rsvStatus == RSV_KARI) {
50: (4) (4) (4) if ((nowDateTime - lastDateTime) > TIMEOUT_KARI) {
51: (4) (4) (4) (4) rsvStatus = RSV_AKI;
52: (4) (4) (4) }
53: (4) (4) }
54: (4) (4) // 予約状況が空きであることを確認し、仮予約処理を行う
55: (4) (4) if (rsvStatus == RSV_AKI) {
56: (4) (4) (4) psUp.setInt(1, RSV_KARI); psUp.setString(2, loginUserID); psUp.setString(3, "");
57: (4) (4) (4) psUp.setString(4, ""); psUp.setLong(5, nowDateTime);
58: (4) (4) (4) psUp.setString(6, rsvDate);
59: (4) (4) (4) psUp.setString(7, rsvTime); psUp.setString(8, rsvBiyoshi);
60: (4) (4) (4) psUp.executeUpdate(); &bold(){&color(red){← [仮予約の更新を行うところ]}}
61: (4) (4) (4) (省略)[図6の処理を引き継ぐために、選択した予約枠の情報をサーブレットのセッション情報に保存する]
62: (4) (4) (4) (省略)[画面3のHTML出力を行う]
63~ (管理人省略)
}}
** 図5 サーブレット"WakuClick" 抜粋終わり
肝になるのは、42行目の&bold(){&color(red){[予約枠の予約状況を参照!]}}と60行目の&bold(){&color(red){[仮予約の更新を行うところ]}}です。
一般的なRDBMSを使用している場合、αの更新の後に、βが更新して上書きというシナリオは、2パターン考えられます。
** パターン1
|1|αが&bold(){&color(red){[予約枠の予約状況を参照!]}}|
|2|αが&bold(){&color(red){[仮予約の更新を行うところ]}}&br()ここでαのトランザクションが行ロック|
|3|βが&bold(){&color(red){[予約枠の予約状況を参照!]}}|
|4|βが&bold(){&color(red){[仮予約の更新を行うところ]}}&br()ロック開放待ち|
|5|αがコミットと同時にロック開放|
|6|βがコミット|
** パターン2
|1|αが&bold(){&color(red){[予約枠の予約状況を参照!]}}|
|2|βが&bold(){&color(red){[予約枠の予約状況を参照!]}}|
|3|αが&bold(){&color(red){[仮予約の更新を行うところ]}}&br()ここでαのトランザクションが行ロック|
|4|βが&bold(){&color(red){[仮予約の更新を行うところ]}}&br()ロック開放待ち|
|5|αがコミットと同時にロック開放|
|6|βがコミット|
今回の問題では、表7の順序2に「β」が指定されているのでパターン2が該当するので、表7は以下のようになります。
** 表7 仮予約が無効になる処理の順序
|順序|対象の顧客|処理|
|1|α|図5の42行目|
|2|β|図5の【 42 】行目|
|3|【 α 】|図5の【 60 】行目|
|4|【 β 】|図5の【 60 】行目|
[[設問に戻る>資格試験/情報処理技術者試験/情報セキュリティスペシャリスト/過去問2013年春午後2/問1#設問]]