DB〜トランザクション制御【H29午後1問2】

DB

ここでは、データベーススペシャリスト試験の対策として、『トランザクション制御』についての問題を扱った過去問の解説を紹介します。対象は、平成29年度午後1問2の問題となります。

出題趣旨

【出題趣旨】
・アプリケーション処理内容の理解
・実行順序の設計
・SQL設計能力
・トランザクション制御及び排他制御の理解
・適切な同時実効性を満たす設計能力
【設問1】SQL
【設問2】デッドロック
【設問3】排他制御

設問1

設問1はSQLの穴埋め問題である。

設問2

設問2(1)

設問2(1)はデッドロックが発生する状況を答える問題。
在庫引当APが、REPEATABLE READで複数同時に実行されるとデッドロックが発生する場合があるが、どのような場合か?AP間のSQL実行状況を、図2中の②を用いて答える問題。
この場合、次を確認する。
・トランザクションのISOLATIONレベル
・ロックの種類(共有ロックや専有ロック)や粒度
・アプリケーションでの処理内容

ISOLATIONレベル

ロックの種類(共有ロックや専有ロック)や粒度

処理の確認
【処理①】
”倉庫コード”、”部品番号”、[hv3]に出庫数を指定して、”在庫”テーブルから”倉庫内在庫数量”を[hv4]に、”出庫対象在庫数量”を[hv5]に入力される。
これらの値は、”在庫”テーブルの主キー{倉庫コード、部品番号}で、「各テーブルには主索引が定義されている」のと記載があるで、索引スキャンとなり、記載の通り「索引から読み込んだ行だけがロック対象になる」。
<在庫引当AP>
REPEATABLE READ;データ参照時に共有ロックをかけ、トランザクション終了時に解放
つまり、該当行に対する共有ロックはトランザクション終了時まで保持される。
[hv4]ー[hv5]と[hv3]を比較し、出庫可能な場合だけ、以降を実行する。

【処理②】
指定した”倉庫コード”、”部品番号”に対して、”在庫”テーブルの出庫対象在庫数量に[hv3;出庫数量]を加えた値に更新する。
”在庫”テーブルには処理①から引き続き行の共有ロックがかかっている。

【処理③】
対象の”出庫番号”に対して、”出庫”テーブルの”処理状況”を’引当実施’に更新する。
ここで、”出庫”テーブルの”出庫番号”ごとの行ロックを専有ロックでかけ、トランザクション終了時まで解放待ちとなる。

【処理④】COMMIT

デッドロックになるパターンを考える。
デッドロックの条件としては、
・同じ行を違う順序でロックをかけ、お互いのロック待ちとなる場合である。
処理①では、”在庫”テーブルの指定した”倉庫コード”、”部品番号”に対して、参照のために「共有ロック」をかけている。
処理②では、”在庫”テーブルの指定した”倉庫コード”、”部品番号”に対して、更新のために「専有ロック」をかけている。
処理順序とロック順序を整理すると、”在庫”テーブルの”倉庫コード”、”部品番号”に対して、
処理①開始前;ロックなし→処理①実施中;共有ロック→処理①終了後;共有ロック中(トランザクション終了まで解放待ちのため)→処理②開始前;共有ロック中→処理②実施中;共有ロック・専有ロック→処理②終了後;共有ロック・専有ロック実施中(トランザクション終了まで解放待ち)→処理③→処理④COMMIT;ロック解放(トランザクション終了のため)のようになる。
よって、処理①での共有ロック時と処理②の専有ロック時で、同じ行(同じ”倉庫コード”、同じ”部品番号”)で、異なる順番(①で入力した”倉庫コード”、”部品番号”の順序が異なる)の場合に、処理①と処理②の間で、ロック解放待ち状態となり、デッドロックとなる。
例えば、A:処理①で共有ロック→B:処理①で共有ロック(共有ロックなので、Aが共有ロックしていてもBは共有ロックできる)→A:処理②で専有ロック(Bが共有ロック中なので、Aは専有ロックできない)→B:処理②で専有ロック(Aが処理①で共有ロック中(処理②で専有ロックしたいが、Bが共有ロック中で、解放待ちの状態))の場合です。
したがって、回答としては、
『”在庫”テーブルの同じ行に対して、先行するAPの①と②の間で、後続のAPの①が実行された場合』となります。

時点AP1AP2ロック状態
処理①:在庫(A)検索(Sロック)A: S(AP1)
処理①:在庫(A)検索(Sロック)A: S(AP1, AP2)
処理②:在庫(A)更新(Xロック要求)→ AP2のSがあるため待機A: S(AP1, AP2), AP1はX待機
処理②:在庫(A)更新(Xロック要求)→ AP1のSがあるため待機相互待ち(デッドロック)

ポイント

処理②のロックは「S+X」両方?」
→ 「SからXへの昇格」が正しい表現。結果的に「Xロックが取れるまでSを保持したまま待つ」挙動。

共有ロック中は専有ロックをかけられない?
→ ✔その理解で正しい。他セッションのSが残っている限りXロックは取れない。

共有ロック中に共有ロックはかけられる?
→ ✔その理解も正しい。Sは複数セッションで共有できる。

デッドロックは「同じ行を異なる順序でロックした場合」だけ?
→ 典型はそれですが、本問は「Sロック取得 → 相手もSロック → 双方がX昇格要求」で起きるパターン。
→ 順序の違いによるデッドロック(典型例)と、今回のように「昇格時にお互いのSロックが邪魔する」ケースもある。

デッドロック対策

(A) ロック順序の統一

  • 全てのアプリケーションが 同じ順序 で表や行をロックするように設計する。
  • 例:必ず「在庫テーブル → 出庫テーブル」の順で処理。
    → 異なる順序でロックを取るのがデッドロックの主原因なので、これを避ける。

(B) SELECT FOR UPDATEの利用

  • 参照と同時に専有ロックを取得しておく。
  • メリット: 更新時の昇格待ちを防げる。
  • デメリット: 競合が起きやすくなる(同時にSELECTすらできなくなる)。

SELECT FOR UPDATEとは?
  • 目的
    SELECT で読み込んだ行に対して、更新を前提とした専有ロック(Xロック)を取得する
  • 通常のSELECT
    • REPEATABLE READ なら共有ロック(S)を取る → 他のセッションもSELECTは可能
    • その後にUPDATEすると、SロックからXロックへの昇格が必要になり、そこで競合・デッドロックが起こり得る
  • SELECT FOR UPDATE
    • 読み取った時点でXロックを取得する
    • 以降のUPDATE時にロック昇格が不要になるので、デッドロックを防ぎやすい

(C) アプリケーション側でのリトライ処理

  • DBMSはデッドロックを検出すると一方を強制的にROLLBACKする。
  • その場合、アプリケーションで 再実行(リトライ)処理 を実装しておけば業務的に回避可能。

(D) ロック粒度の調整

  • 行ロックを基本とし、範囲ロックやテーブルロックを避ける。
  • 索引利用で「不要な行にロックをかけない」ことも有効。

(E) トランザクション設計の見直し

  • 長時間ロックを保持しないように処理を短くする。
  • 更新と関係ないSELECTはなるべくロックなし(READ COMMITTEDやスナップショット分離を検討)。

設問2(2)

設問2(2)は、在庫引当APがREAD COMMITEDで、同じ倉庫の同じ部品に対して、複数実行されると、在庫数量が不正になる恐れがある。AP2の処理①〜④が、t2、t4、t6、t8のどの時間で実行された場合か、該当する時間帯にAP2の処理①〜④を記入する問題である。また、この状況が発生した場合の在庫数量が不正になる状態とはどんな状態か?について答える。
AP1:先行しているAP
AP2:問題を引き起こすAP
t1〜t8:時間帯を示す。
【AP1】t1;①、t3;②、t5;③、t7;④である。

READ COMMITEDとは?
・ノンリピータブルリードとファントムリードが発生する
よって、この2パターンの場合について考えれば良い。
・ノンリピータブルリード;同じ行を繰り返し読むと値が変わる
・ファントムリード;範囲条件で検索すると、途中で別トランザクションにより「行の追加/削除」が起き、結果集合が変わる(例:新しい部品が別トランザクションでINSERTされて結果に追加される)

【READ COMMITED時の処理の流れ】
処理①;開始時に共有ロックをかけ、終了時に共有ロックを解放する。
処理②;開始時に専有ロックをかけ、処理③・④終了時に専有ロックを解放する。
処理③;処理②から引き続き、専有ロックがかかっている。
処理④;開始時は処理②からの専有ロックがかかっているが、終了時に専有ロックを解放する。
ロックをかけられるタイミングとしては、A:処理①終了時かB:処理②〜④終了時となる。

【不正になるパターンの検討】
1つ目は、[t1]でAP1が処理①の終了後に、[t2]でAP2が処理①〜④を実行した場合で、[t1]のAP1の処理①での参照内容と、[t3]のAP1の処理②での更新時の内容が変更されている恐れがあることだ。いわゆる、ノンリピータブルリードが発生した場合である。つまり、回答としては、『[t2]で処理①〜④が終了した場合』となる。
→ これは同じ行を「読むとき」と「更新するとき」で値が変わる → ノンリピータブルリード

2つ目は、AP1の処理①の後、[t2]でAP2が処理①でデータを共有ロックで参照し、その後、[t3〜t7]でAP1の処理②〜④が終了し、[t8]でAP2が処理②の専有ロックをかけた場合、[t2]の共有ロック時のデータの値と[t8]の専有ロック時のデータの値が異なり、不正となることがある。いわゆる、ノンリピータブルリードが発生した場合である。つまり、回答としては、『[t1]で処理①が終了し、[t8]で処理②〜④が終了した場合』となる。
→ 結果、AP2が t8 で更新すると矛盾が発生する → これも ノンリピータブルリード

時間帯AP1の処理1パターン目(t2でAP2が①〜④実行)2パターン目(t2でAP2が①のみ、t8で②〜④実行)
t1① 在庫数量参照(共有ロック→Aで解放)
t2① 在庫数量参照(共有ロック→Aで解放)②〜④ 在庫更新(専有ロック→Bで解放)① 在庫数量参照(共有ロック→Aで解放)
t3② 在庫更新(専有ロック獲得→Bで解放)
t5③ 在庫更新(専有ロック継続)
t7④ 在庫更新(専有ロック→Bで解放)
t8② 在庫更新(専有ロック獲得→Bで解放)③ 在庫更新④ 在庫更新
結果不正発生(パターン①)AP1が①で読んだ数量と、AP1②の更新対象がずれる不正発生(パターン②)AP2が①で読んだ数量と、②以降の更新対象がずれる

この状況が発生した場合の在庫数量が不正になる状態とはどんな状態か?について答える。
不正になる状況としては、「参照時と更新時で値が異なる可能性がある」ということである。これが、どのような状態を引き起こすかというと、処理②以降の条件として「出庫可能な場合だけ実行する」とあるように、データの値が異なることにより出庫できない状況がある、ということである。したがって、回答としては、『出庫対象在庫数量が倉庫内在庫数量を超える』となる。

,

まとめ

  • READ COMMITTEDとは
    • トランザクション内で「参照するたびにコミット済みの最新データを読む」方式。
    • 特徴として以下の不正が発生する可能性がある:
      • ノンリピータブルリード:同じ行を2回読んだときに、間に他トランザクションが更新・コミットすると値が変わってしまう。
      • ファントムリード:範囲検索したときに、間に他トランザクションが挿入・削除を行うと、行数や集合が変わってしまう。
  • ロックの扱い
    • 参照系の共有ロックは「処理①終了時(A)」で解放される。
    • 更新系の専有ロックは「処理②〜④終了時(B)」まで保持される。
  • この違いにより発生する不正
    1. パターン①(t2でAP2が①〜④実行)
      • AP1の①で参照した数量と、AP1の②更新対象がずれて不正が起こる。
    2. パターン②(t2でAP2が①実行、t8で②〜④実行)
      • AP2の①で読んだ数量と、②以降で更新する数量がずれて不正が起こる。

設問2(3)

設問3(3)では、SQLの問題である。UPDATEと関連する述語が入る。
よって、『CURRENT』。
〜UPDATE 在庫 SET 出庫対象在庫数量=出庫対象在庫数量+ :hv3
 WHERE 【CURRENT】 OF 在庫カーソル〜

解説ポイント:CURRENT OFとは?

  • カーソルで参照している「現在行」 を更新または削除するためのSQL構文。
  • 主に UPDATEDELETE 文と組み合わせて使用する。
  • WHERE CURRENT OF カーソル名 とすることで、カーソルでフェッチした行に直接処理を行える。

メリット

  • 主キーや複雑な検索条件を書かなくても、カーソルが指している行を一意に特定できる
  • カーソル処理と更新処理をセットで記述する際に便利。

設問3

設問3は、スループット向上に関する問題である。

設問3(1)

設問3(1)は、スループット向上に関する穴埋め問題である。

【出庫確定APの処理概要】
<設定環境>
・”出庫”テーブルの”出庫番号”の値の範囲指定で各プロセスに均等に配分
・REPEATABLE READで並列実行
<処理フロー>
処理①:”出庫”テーブルに登録されている、指定された範囲内の出庫番号の昇順に、各行ごとに次の2処理を行う。
 処理②:”出庫”テーブルを参照して、処理要否を判定。処理状況が”引当実施”の場合だけ次のA〜Cを実行。
  A;”在庫”テーブルの倉庫内在庫数量を更新(出庫数量分を減算)
  B:”在庫”テーブルの出庫対象在庫数量を更新(出庫数量分を減算)
  C:”出庫”テーブルの処理状況を”出庫実施”に更新
 処理③:”出庫”テーブルの指定された範囲内の全ての行の処理が完了したら、COMMIT

【回答について考える】
複数の”出庫”を並列に処理するが、同じ【ア】【イ】に対する出庫が複数存在するので、”【ウ】”テーブルの更新で【エ】が発生する。
まず、【ア】【イ】だが、”出庫”に対する並列処理で参照する箇所のことを示している。”出庫”の処理は、”倉庫コード”と”部品番号”を入力して処理していた。よって、【ア】【イ】には『倉庫コード』と『出庫番号』が入る。
【ウ】については、”出庫”の処理で影響するテーブル名が入ると考えられる。「”出庫”テーブルを参照して、外皮を判定。」以下の文章を見ると、「”在庫”テーブルの更新」があるので、【ウ】には『在庫』が入ると考えられる。
【エ】に関して、(【ウ】;在庫)テーブルの更新時に発生することである。
処理フローを確認すると、次のようになる。
処理①→対象行を共有ロック→<判定>→[OK]→処理②→対象行を専有ロック→処理③→終了
処理①→対象行を共有ロック→<判定>→[NG]→終了
つまり、複数の出庫処理(処理①)での共有ロックから、”在庫”テーブルが該当する処理②の専有ロックに移るまでで、共有ロックの解放待ちが発生する。したがって、【エ】は『ロックの解放待ち』となる。

設問3(2)

設問3(2)では、設問3(1)のボトルネック解消のための出庫確定APの変更点に関する穴埋め問題である。

【オ】【カ】については、各プロセスの配分の範囲指定に関して、”出庫番号”ではなく、【オ】と【カ】の組み合わせの値に変更する、というものである。
ここで、範囲指定が”出庫番号”であることの問題は、”出庫”テーブルと”在庫”テーブルの参照・更新の際に、対象行の読込み順があべこべになる可能性がある、ということである。つまり、”出庫番号”で並べた場合、対象行(”倉庫コード”と”部品番号”で指定される)はどのように配置されているかは、入力した人次第になってしまう。そのため、当然出庫番号ごとに、対象行の順番が異なる。
よって、”在庫”テーブルと”出庫”テーブルを同じ順序で読み込めば良いので、在庫確認を行うのは、”出庫”テーブルの外部キーの”出庫元倉庫コード”と”部品番号”となる。【オ】;”出庫元倉庫コード”、【カ】;”部品番号”となる。

【キ】に関しては、【オ】;”出庫元倉庫コード”、【カ】;”部品番号”列に複数列索引を定義するが、そのテーブル名【キ】を答えるものである。
”在庫”テーブルか”出庫”テーブルのどちらかになるが、”在庫”テーブルの主キーは”倉庫コード”と”部品番号”であり、主キー索引があるだろうから不要である。一方、”出庫”テーブルの主キーは、”出庫番号”であり、また、処理②の”倉庫内在庫数量”と”出庫対象在庫数量”の更新の行いたい。そのため、”出庫”テーブルに対して、複数列索引がない場合、「索引を使わずに、テーブルスキャンで全ての行に順次アクセスする場合、検索条件に合致するかいなかに関わらず全行がロック対象となる」と記載があるように、テーブルスキャンでの全行順次アクセスとなるので、これを避けるために、『出庫』テーブルに索引定義をする。



【ク】【ケ】は、上の複数列索引を定義していない場合の影響について答える問題で、
【ク】は、この索引がない場合、自プロセスの対象行かの判定のための参照がどうなるか?
【ケ】は、他プロセスがどうした行を参照しようとして、ロックの解放待ちとなり、別のボトルネックが生じる。
というものである。
【ク】について、「索引を使わずに、テーブルスキャンで全ての行に順次アクセスする場合、検索条件に合致するかいなかに関わらず全行がロック対象となる」と本文中にあるので、【ク】は『テーブルスキャン』となる。
【ケ】は、ロックの解放待ちとなるのは、他のプロセスが何をしている行か、である。【ク】で「全行ロック」となっていることがわかるので、これが解消されないとロックの解放待ちとなる。したがって、『更新』または『専有ロック』となる。

確認ポイント
・異なるテーブルの対象行の読み込み順を揃えるのが鉄則。(更新待ち・デッドロック対策)
・全行ロック=専有ロックなのか?

デッドロックポイント整理

ロックの競合に基づくパターン(最も典型的)

パターン概要隔離レベル例(T1とT2のトランザクション)
① 資源獲得順序の逆転異なるトランザクションが複数の資源(データ行、ページ、テーブルなど)を異なる順序でロックし合うパターン。専有ロック(Xロック)同士の排他関係で発生することが多いです。全レベル (特にRead Committed以上)T1: 行Aをロック → 行Bを要求 (T2待ち) T2: 行Bをロック → 行Aを要求 (T1待ち)
② SロックとXロックの循環待ち異なるトランザクションが同一の資源に対し、Sロックを保持したまま、Xロックへの昇格(または要求)を同時に試みるパターン。Sロックの保持期間が長い隔離レベルで発生しやすいです。REPEATABLE READT1: 行AにSロック保持 → Xロック要求 (T2のSロック待ち) T2: 行AにSロック保持 → Xロック要求 (T1のSロック待ち)

ロック粒度とデータ範囲に基づくパターン

パターン概要ロック対象例(T1とT2のトランザクション)
③ 複数テーブル/データ範囲の順序逆転複数のテーブルや異なるデータ範囲を対象とするトランザクション間で、テーブルごと、またはキー値の範囲ごとの処理順序が逆転する場合。テーブル、ページ、インデックスキー範囲T1: テーブルAを更新 → テーブルBを更新 T2: テーブルBを更新 → テーブルAを更新
④ 粒度の異なるロックの競合単一行/単一ページをロックするトランザクションと、テーブル全体またはインデックス範囲をロックするトランザクションが競合するパターン。行ロックとテーブルロックT1: テーブル全体に意図的Xロック → 行ロック要求 (T2待ち) T2: 単一行にXロック → テーブルXロック要求 (T1待ち)
⑤ インデックスキー範囲ロックの競合ファントムリードを防ぐためにかけられるキー範囲ロックが、他のトランザクションによる行の挿入/削除と競合するパターン。キー範囲 (GAP Lock)T1: 範囲ロックを保持(特定の範囲への挿入を禁止) T2: その範囲に行を挿入 → ロック待ち

その他(アプリケーション起因)のパターン

パターン概要特徴
⑥ アプリケーションによるロックの明示制御データベースの自動ロックではなく、SELECT FOR UPDATEなどの明示的なロックが異なる順序で行われることで発生。SQLレベルでのロック順序制御の誤り
⑦ 複数の接続プール/プロセス間でのリソース競合データベース外のリソース(ファイル、メッセージキューなど)も含め、トランザクションが複数の外部システムのリソースを異なる順序で確保し合うパターン。データベース外の排他制御も絡む

デッドロック発生パターンと対策

発生パターン主な原因有効な対策備考
同一テーブル内で異なる順序で行ロックトランザクションごとに更新順序が異なる(例:T1→A,B、T2→B,A)– 更新順序を統一する(主キー順など)- 更新対象を1行ずつコミット- ロック範囲を明示的に指定最も典型的なデッドロック原因。IPA午後問でも頻出。
共有ロック→専有ロック昇格競合SELECTでSロック保持後にUPDATEするトランザクションが複数同時実行– SELECT後すぐUPDATEせず、更新対象を先に特定する- SELECT FOR UPDATEを使用して最初から排他ロックを取得- アクセス順序を統一REPEATABLE READで特に起こりやすい。
複数テーブルを異なる順序で更新トランザクション間でテーブル更新の順序が不一致– すべての処理でテーブル更新順序を統一(例:常にA→Bの順)- トランザクション粒度を小さくするシステム設計で防ぐのが基本。
親子・構成要素の多重更新親(セット)と子(単品)をまたいで更新順序が不一致– 主キー順・構成順を統一- 親→子または子→親の更新順序を固定- ロック設計を見直す今回のTR3・TR4のようなケース。
インデックス/範囲ロック競合範囲条件(WHERE < など)でNext-Key Lockが重複– インデックス設計を見直す- 検索条件を限定してロック範囲を最小化- 必要ならISOLATION LEVELを下げるInnoDBなどでよく発生。
外部キー制約の親子同時更新親テーブル更新時、子テーブルが外部キー参照で同じ行をロック– 更新順序を統一(親→子)- 外部キーの遅延チェック(DEFERRED制約)を利用- 外部キー制約をアプリで制御複雑なリレーションで発生。
サブクエリによる遅延ロックUPDATE文中の副問い合わせが内部的に別順序で評価– サブクエリを分離して一時テーブルに格納- 更新前に必要データをすべて取得内部的な実行順序が読みにくいため注意。
トリガーやカスケード更新による再帰ロックトリガーや外部キーで同一テーブルを再更新– トリガー処理の再帰呼び出しを避ける- 更新対象を明示的に分離アプリ側で制御するのが安全。

デッドロック回避原則

原則内容
① 更新順序の統一すべてのトランザクションで、テーブル・行のアクセス順序を統一する。
② トランザクションの短縮ロック保持時間を短くする(コミットを早める、細分化する)。
③ ロック範囲の明示化必要な範囲だけ SELECT ... FOR UPDATE で明示ロックする。
④ 再試行制御(リトライ)デッドロック発生を検出したら、トランザクションを自動的に再実行する。
⑤ ロック競合を避ける設計同一データを複数トランザクションが同時更新しないよう設計段階で分離。

ロック方式とデッドロック対策:確認質問&模範回答

ロック方式

質問回答例
1. 共有ロック(Sロック)が設定されている間、他のトランザクションはどのような操作ができますか?他のトランザクションは**参照(SELECT)**はできるが、**更新(UPDATE・DELETE・INSERT)**はできない。
2. 排他ロック(Xロック)は、どのような操作のときに設定されますか?**更新系操作(UPDATE・DELETE・INSERT)**を行うときに設定される。
3. 共有ロックと排他ロックの違いを説明してください。共有ロックは他の読み取りを許可するが、排他ロックは他の操作をすべてブロックする。
4. 参照時に一般的に使用されるロック方式は何ですか?共有ロック(Sロック)またはロックなし(読み取り一貫性を維持する方式)
5. 更新時に使用されるロック方式は何ですか?排他ロック(Xロック)
6. ロックの粒度を「テーブル」「ページ」「レコード」に分ける理由は何ですか?同時実行性能と制御のコストをバランスさせるため。粒度が小さいほど並行性が上がるが、管理コストが増える。
7. ロックの粒度が小さいと、どのような利点と欠点がありますか?利点:同時実行性が高まる。欠点:ロック管理のオーバーヘッドが増える。
8. 楽観的ロックと悲観的ロックの違いを説明してください。悲観的ロックは「競合が起こる前提」で最初からロックする。楽観的ロックは「競合は稀」と考え、更新時にチェックする。

デッドロックに関する質問

質問回答例
1. デッドロックとはどのような状態のことを指しますか?複数のトランザクションがお互いのロック解除を待ち続け、永久に処理が進まない状態
2. デッドロックが発生するための4つの条件を説明してください。①相互排他、②占有と待ち、③非奪取、④循環待ち。
3. 「ロックの取得順序を統一する」ことにはどのような効果がありますか?循環待ちを防ぎ、デッドロックの発生を抑制できる。
4. デッドロックの検出では、どのような仕組みで検出が行われますか?**待ちグラフ(Wait-for Graph)**を用いて循環(サイクル)を検出する。
5. タイムアウト方式とはどのようなデッドロック対策ですか?一定時間待ってもロックが解除されない場合、自動的にトランザクションを中止してデッドロックを回避する方式。
6. デッドロック発生時に「トランザクションをロールバックする」理由は何ですか?デッドロックを解消し、他のトランザクションを進めるため。
7. デッドロックの発生を完全に防ぐことは可能ですか?なぜですか?理論的には難しい。複数トランザクションの並行実行では常に競合の可能性があるため。

応用・理解度チェック

質問回答例
1. SELECT文実行時に、他のトランザクションが同じデータを更新できないようにしたい場合、どのロックを使いますか?**共有ロック(Sロック)**を使用する。
2. UPDATE文を実行中に、他のトランザクションが同じレコードをSELECTするのを許可したい場合、どんな問題が起こる可能性がありますか?**ダーティリード(未確定データの読取)**が発生する可能性がある。
3. デッドロックを検出した場合、どのトランザクションを中止するのが合理的でしょうか?一般に、ロールバックコストの小さい(処理時間の短い)トランザクションを中止する。
4. ロックを「早く取得し、早く解放する」設計にすることのメリットは何ですか?デッドロックの発生を減らし、システムの同時実行性を高められる。
5. データベースの同時実行制御において、ロック以外の手法にはどのようなものがありますか?タイムスタンプ順序制御や**MVCC(多版本同時実行制御)**などがある。
タイトルとURLをコピーしました