令和2年 午後1 問2設問2(2) ISOLATIONレベル
発さんさん
(No.1)
空席管理システムで実行するトランザクションのISOLATIONレベルが、READ COMMITTEDか、REPETABLE READのいずれを設定すべきか、という問いで
回答が後者(REPETABLE READ)で、模範回答が「同時実行した他者が同じ座席を仮予約できないようにするため」となっております。
問題では、READ COMMITTEDとREPETABLE READの違いは、「共有ロックの解放タイミング」であり、前者は、参照終了後、後者はトランザクション終了後、の違いです。
疑問なのは、共有ロックは、他トランザクションからもかけられるため、どちらのISOLATIONレベルにおいても、同時実行で空席フラグがオンである、と参照できてしまいませんか?もちろん、先に共有ロックをかけたほうが、専有ロックをそのままかけられるという点においては、REPETABLE READの方が良いのかもしれませんが、、、
更新(仮予約フラグをオンにする)のときも条件も定かではないですし、共有ロックの解放タイミングの違いだけで、「同時実行した他者が同じ座席を予約できないようにする」とまで言い切れるのでしょうか・・?
通常は空席フラグを参照するときに排他ロックをかけることで、他トランザクションの参照もさせない、だと思うのですが、、釈然としない感じです。。
こちらどのように考えれば腑に落ちますかね・・?
回答が後者(REPETABLE READ)で、模範回答が「同時実行した他者が同じ座席を仮予約できないようにするため」となっております。
問題では、READ COMMITTEDとREPETABLE READの違いは、「共有ロックの解放タイミング」であり、前者は、参照終了後、後者はトランザクション終了後、の違いです。
疑問なのは、共有ロックは、他トランザクションからもかけられるため、どちらのISOLATIONレベルにおいても、同時実行で空席フラグがオンである、と参照できてしまいませんか?もちろん、先に共有ロックをかけたほうが、専有ロックをそのままかけられるという点においては、REPETABLE READの方が良いのかもしれませんが、、、
更新(仮予約フラグをオンにする)のときも条件も定かではないですし、共有ロックの解放タイミングの違いだけで、「同時実行した他者が同じ座席を予約できないようにする」とまで言い切れるのでしょうか・・?
通常は空席フラグを参照するときに排他ロックをかけることで、他トランザクションの参照もさせない、だと思うのですが、、釈然としない感じです。。
こちらどのように考えれば腑に落ちますかね・・?
2025.09.25 00:55
ぶどうさん
★DB ブロンズマイスター
(No.2)
READ COMMITTEDを選んではいけない理由を確認しているだけなんじゃないのかしら。同時実行した他者が同じ座席を予約できないようにするには、READ COMMITTEDか、REPETABLE READのいずれを設定すべきか?という問いだったわけではないでしょう。
2025.09.25 12:25
発さんさん
(No.3)
ありがとうございます。
おっしゃる通り「同時実行した他者が同じ座席を予約できないようにするには、READ COMMITTEDか、REPETABLE READのいずれを設定すべきか?という問いだったわけではない」ですよね、、。
だからこそ、REPETABLE READを設定すべきとする理由の模範回答が「同時実行した他者が同じ座席を予約できないようにする」という答えなのが釈然としない感じでした。。
問題文の条件をそのまま活かすのだとしたら、「先に購入しようとした利用者が排他ロックをかける前に他の利用者から割り込まれるのを防ぐ」みたいなよくわからない回答になりそうだなと思ったところですが、まぁなんやかんや排他制御を強め流みたいなことを書けば点数になったのかもしれませんね。。
おっしゃる通り「同時実行した他者が同じ座席を予約できないようにするには、READ COMMITTEDか、REPETABLE READのいずれを設定すべきか?という問いだったわけではない」ですよね、、。
だからこそ、REPETABLE READを設定すべきとする理由の模範回答が「同時実行した他者が同じ座席を予約できないようにする」という答えなのが釈然としない感じでした。。
問題文の条件をそのまま活かすのだとしたら、「先に購入しようとした利用者が排他ロックをかける前に他の利用者から割り込まれるのを防ぐ」みたいなよくわからない回答になりそうだなと思ったところですが、まぁなんやかんや排他制御を強め流みたいなことを書けば点数になったのかもしれませんね。。
2025.09.25 21:20
やまきんさん
(No.4)
空席管理システム
(a) トランザクションを開始する
(b) 座席数分、次の処理を繰り返す
・空席フラフがオンか確認する
・仮予約フラグがオフか確認する
・仮予約フラグをオンにする
(c) コミット
for (int i =0 ; i<=n; i++) {
②s_elect 空席フラフ from 座席状況 where XXX=? 共有ロック
②s_elect 仮予約フラグ from 座席状況 where XXX=? 共有ロック
③u_pdate 座席状況 set 仮予約フラグ=on where XXX=? 専有ロック
}
ISOLATION レベル repeatable read (ケース1) =>デッドロック
TXA TXB
t1 ①
t2 ②
t3 ①
t4 ②
t5 ③
t6 ③
t7
ISOLATION レベル repeatable read (ケース2) =>デッドロック
TXA TXB
t1 ①
t2 ②
t3 ①
t4 ②
t5 ③
t6 ③
t7
ISOLATION read committed (ケース3) =>ダブル仮ブッキング
TXA TXB
t1 ①
t2 ②
t3 ①
t4 ②
t5 ③ 仮予約フラグ=ONでコミットできてしまう
t6 ③
t7
複数のトランザクションを扱う時に、
repeatable readはデータが不正な状態に陥ることはないですが、
その代わりにデットロックが発生する可能性があります。
read committedはデータが不正な状態になる可能性がありますが(ダブルブッキング、在庫数量マイナーとか)
デッドロックが発生しにくい状態にあります(もちろん、同じ順番で実行する前提で)
もしread committedを選ぶなら、①と②のselect参照で FOR UPDATE句「専有ロック」をつけないといけないですかね。
今回はデットロック起きてもいいから、ダブルブッキングを極力発生させたくないですかね
小職の理解が間違っていたら、ご指摘をください。
(a) トランザクションを開始する
(b) 座席数分、次の処理を繰り返す
・空席フラフがオンか確認する
・仮予約フラグがオフか確認する
・仮予約フラグをオンにする
(c) コミット
for (int i =0 ; i<=n; i++) {
②s_elect 空席フラフ from 座席状況 where XXX=? 共有ロック
②s_elect 仮予約フラグ from 座席状況 where XXX=? 共有ロック
③u_pdate 座席状況 set 仮予約フラグ=on where XXX=? 専有ロック
}
ISOLATION レベル repeatable read (ケース1) =>デッドロック
TXA TXB
t1 ①
t2 ②
t3 ①
t4 ②
t5 ③
t6 ③
t7
ISOLATION レベル repeatable read (ケース2) =>デッドロック
TXA TXB
t1 ①
t2 ②
t3 ①
t4 ②
t5 ③
t6 ③
t7
ISOLATION read committed (ケース3) =>ダブル仮ブッキング
TXA TXB
t1 ①
t2 ②
t3 ①
t4 ②
t5 ③ 仮予約フラグ=ONでコミットできてしまう
t6 ③
t7
複数のトランザクションを扱う時に、
repeatable readはデータが不正な状態に陥ることはないですが、
その代わりにデットロックが発生する可能性があります。
read committedはデータが不正な状態になる可能性がありますが(ダブルブッキング、在庫数量マイナーとか)
デッドロックが発生しにくい状態にあります(もちろん、同じ順番で実行する前提で)
もしread committedを選ぶなら、①と②のselect参照で FOR UPDATE句「専有ロック」をつけないといけないですかね。
今回はデットロック起きてもいいから、ダブルブッキングを極力発生させたくないですかね
小職の理解が間違っていたら、ご指摘をください。
2025.09.27 09:49
ぶどうさん
★DB ブロンズマイスター
(No.5)
>No4
デッドロック云々は、ISOLATIONレベルを変更すれば解決できるの?
2025.09.27 18:49
やまきんさん
(No.6)
>No5
あらゆるところで処理順を同じに統一して、デッドロックが発生は格段に減らせると思いますが、
実際には100%の解決は保証されません。
したがって、隔離レベルを変更しても根本的な解決にはならない
と理解しています。
2025.09.27 22:36
ぶどうさん
★DB ブロンズマイスター
(No.7)
>No4
>今回はデットロック起きてもいいから、ダブルブッキングを極力発生させたくないですかね
No4ではISOLATIONレベルとデッドロックを一緒に検討しているけれど、No6の理解ならばそれぞれ別々にきりわけて段階的に検討するんじゃないの?
アレンジ再出題された際には、デッドロックも含めて解答するのは避けたほうが無難でしょう。(採点講評を参考)
2025.09.28 01:27
やまきんさん
(No.8)
>No7
なるほどです。
🔹採点評価 引用
{
設問 2 は、正答率が平均的であったが、(2)の理由については正答率が低かった。特に、ロックの解放時間の短縮や、デッドロックを回避することを理由に挙げたものが散見された。オンラインシステムでは、同時実行される要求が、相互に影響して予期せぬ結果を発生させることのないように、処理内容を注意深く設計する必要がある。設問中の処理内容と状況記述から、適切な ISOLATION レベルを読み取ってほしい
}
🔹記述 引用
{
16ページ、見直しに当たって、同時実行されたトランザクションのやり直しが極力発生しないようにする方針とした
}
デッドロックの記述は一切記載されていないですし、
この段階では、上記の方針だけを考えればいいというわけですね
2025.09.28 07:50
発さんさん
(No.9)
すみません、回答ありがとうございます。
確かに共有ロックをお互いにかけて、共有ロックがトランザクション終了時まで解放されなければ、お互いがロック解放待ちで専有ロックがかけられなくなる、確かにそうですよね、完全に失念していました、、、。
それであれば、確かにお互いが共有ロックをかけて、参照後すぐに解放するならば、デッドロックが発生しない代わりに、いずれも更新ができてしまう。
REPETABLE READのほうは、ダブルブッキングを防ぐことができる代わりに、デッドロックを起こす可能性があり、利用者へは不便。今回はどちらの方が問題が大きいか、を考えて、やはり重複で予約できてしまうことのほうが影響は大きい、そのため、READ COMIITEDを選択するといった感じなのでしょうか。
すみません大変助かりました、質問してよかったです、ありがとうございました。
確かに共有ロックをお互いにかけて、共有ロックがトランザクション終了時まで解放されなければ、お互いがロック解放待ちで専有ロックがかけられなくなる、確かにそうですよね、完全に失念していました、、、。
それであれば、確かにお互いが共有ロックをかけて、参照後すぐに解放するならば、デッドロックが発生しない代わりに、いずれも更新ができてしまう。
REPETABLE READのほうは、ダブルブッキングを防ぐことができる代わりに、デッドロックを起こす可能性があり、利用者へは不便。今回はどちらの方が問題が大きいか、を考えて、やはり重複で予約できてしまうことのほうが影響は大きい、そのため、READ COMIITEDを選択するといった感じなのでしょうか。
すみません大変助かりました、質問してよかったです、ありがとうございました。
2025.09.28 13:17