あるトランザクション処理は, ①共有領域から値を読み取り, ②読み取った値に数値を加算し, ③結果を共有領域に書き込む手順からなっている。複数のトランザクションを並列に矛盾なく処理するためには, トランザクション処理のどの時点で共有領域をロックし, どの時点でロックを解除するのが適切か。 時間(上から下へ進む) - 時点(a) - ① 共有領域から値を読み取り - 時点(b) - ② 読み取った値に数値を加算 - 時点(c) - ③ 結果を共有領域に書き込む - 時点(d)
平成25年度 秋期 ITパスポート試験 問67
テクノロジ系データベース › トランザクション処理
这道题的解析和你的作答记录。
問67
頻出度★☆☆
解説
問 67
错误ア
加锁在时点(a) 这一点是正确的,但解锁在时点(c),也就是在 ③写入之前。若在时点(c) 解锁,共享区域中还留着旧值就会被其他事务读到,之后本事务再写入,于是其中一方的加法就会丢失(丢失更新)。由于没有保护写入操作,所以不合适。
- イ
正解 正确答案是 イ(加锁=时点(a),解锁=时点(d))。本处理接触共享区域的地方有 ①读取 和 ③写入 两处,而 ② 的加法是以 ① 读到的值为前提的。也就是说,只有保证「① 读到的值在 ③ 写回之前不会被其他事务修改」,结果才不会产生冲突。因此加锁应在 ①读取之前=时点(a) 进行,解锁应在 ③写入之后=时点(d) 进行。这样一来 ①~③ 这一连串操作就成为不可分割的处理单元,其他事务在时点(d) 之后读到的是「更新后的值」,因而不会发生加法被抹掉的事故(丢失更新)。反过来,只要把加锁范围稍微缩小一点,读取与写入之间就会留出让其他事务插入的余地。
错误ウ
加锁在时点(b),也就是在 ①读取之后,因此读取处于无保护状态,多个事务有可能读到同一个旧值。而且解锁在时点(c),位于 ③写入之前,所以写入也没有受到保护。读取和写入都在排他范围之外,是最不合适的组合。
错误エ
解锁在时点(d) 这一点是妥当的,但加锁在时点(b),位于 ①读取之后。由于时点(a)~(b) 之间的读取没有受到保护,若两个事务读到同一个值后各自进行加法和写入,后写入的值就会覆盖先前的更新,加法会少算一次。锁必须在读取共享区域之前就加上。
ここがポイント
- 排他控制(加锁)的范围应当是「从读取共享数据之前一刻,到写回之后一刻」。如果不把从读取到写入的整个过程当作一个不可分割的单元加以保护,就会发生丢失更新(更新被覆盖而消失)。
- 在「读取 → 计算 → 写入」形式的更新处理中,写入的值以读取时刻的值为前提,因此只对读取加锁、或只对写入加锁,都无法保持一致性。
用語