データ操作とトランザクション処理

snack
snack

DBMSの機能については「データベース方式」のところで簡単に触れたっすが、ここではより具体的に見ていくっすよ。

ボキタロー
ボキタロー

この機能があるからこそ、単なるファイル保存ではなくデータベースでなくてはならない意味があるんだよね。

snack
snack

そうっすね。データを有効かつ効率的、安全に活用するためには欠かせない機能っす。ITパスポート試験では頻出っすから頑張って勉強するっすよ。

目標・データベースからのデータの抽出などの操作を理解する。
・データベースのトランザクション処理を理解する。
説明・関係データベースを活用するために,必要なデータ操作を理解する。
・複数の利用者によるデータの参照や更新に備えて,同時実行制御(排他制御),リカバリ機能などによってデータベースを保全する必要があることを理解する。
データ操作とトランザクション処理の概要

データ操作

関係データベース(リレーショナル型データベース)における代表的なデータ操作には以下のものがあります。これらは主にSQLにおける基本的な操作です。

挿入新しいデータを表(テーブル)に追加する操作
更新既存のデータを変更する操作
選択条件を満たす行(レコード)を抽出する操作
射影指定した列(フィールド)のみを取り出す操作
結合複数の表(テーブル)を結びつけて新しい関係を得る操作

トランザクション処理

トランザクション処理とは

トランザクション処理とは、データベースなどのシステムにおいて、一連の処理をひとまとまりの単位(トランザクション)として扱い、すべてが成功するか、すべてが失敗して元の状態に戻るかのどちらかにする処理方式です。

たとえば、AさんがBさんに1万円を振り込む場合の処理は以下のようになります。

①Aさんの口座から1万円を引く(出金処理)

②Bさんの口座に1万円を足す(入金処理)

このどちらか一方だけが成功すると、データの整合性が崩れます。そのため、この一連の処理はトランザクションとしてまとめ、両方成功したときのみ確定(コミット)し、どちらかが失敗した場合は一連の処理が最初からなかったこととしてすべて取り消されます(ロールバック)。

入金処理が失敗すると出金処理からなかったこととして考え、出金処理前の状態に戻します。

さらっと学習【ACID特性】

トランザクション処理に求められる4つの性質をACID特性と呼びます。

  1. Atomicity(原子性)
    すべての処理が成功するか、1つでも失敗すれば全体が取り消される(ロールバックされる)。
  2. Consistency(一貫性)
    トランザクション処理前後で、データの整合性が保たれる。
  3. Isolation(独立性)
    他のトランザクションの影響を受けずに処理が行われる。
  4. Durability(永続性)
    処理が完了した後は、システムが障害を起こしても結果が失われない。

2相コミットメント

複数のデータベースやシステムにまたがるトランザクション(分散トランザクション)で、すべての参加者に対して一貫性のあるコミットまたはロールバックを保証する手法を2相コミットメントと呼びます。

たとえば、A社とB社の別々のデータベースに対して1つのトランザクションを行う場合、片方だけが成功してもう片方が失敗すると整合性が壊れます。それを防ぐために、中央調整者(コーディネーター)が全体を管理し、全体を成功か失敗かのどちらかに統一するのが2相コミットメントの役割です。

2相コミットメントでは、第1フェーズでコーディネーターが各参加者に「このトランザクションをコミットできるか?」を問い合わせます。各参加者は、コミット可能なら “Yes”、ダメなら “No” を返します。

第2フェーズで、全員が “Yes” であればコーディネーターは「コミットしてOK」と全員に通知し、第1フェーズで一定時間返答が受け取れない場合や1人でも “No” であればコーディネーターは「中止」と全員に通知します。各参加者は通知を受けて、コミットかロールバックの処理をそれぞれ実行します。

同時実行制御(排他制御)

排他ロック

DBMS(データベース管理システム)における同時実行制御(排他制御)とは、複数のユーザーやアプリケーションが同時にデータベースにアクセス・操作する際に、データの整合性や一貫性を保つための仕組みです。

AさんとBさんが同時にデータベースの顧客情報にアクセスしたとします。このとき、Aさんが顧客の氏名を「鈴木花子」に変更してもBさんが見ている画面では変更前の「田中花子」のままです。

もし排他制御がなければ、Aさんの変更後にBさんが住所を「大阪府」に変更して保存すると、氏名は「田中花子」で上書きされてしまい、Aさんが行った氏名の変更がなかったことになってしまいます。

このような事態を回避するために排他制御が必要となるわけです。

snack
snack

排他制御は、ACID特性の一貫性(Consistency)と独立性(Isolation)を保証するために不可欠っすよ。

主な排他制御の方法にはロック方式があります。ロック方式とは、データベースにおける排他制御の代表的な手法で、複数のトランザクションが同じデータに同時にアクセスしないように制限をかける方法です。

デッドロック

ロック方式の課題(欠点)として、複数のトランザクションがお互いにロックの解除を待ち続けることで、永久に処理が進まなくなる状態になることがあります。この状態のことをデッドロックと呼びます。

(例)
・トランザクションAは、データXを参照した後にデータYを参照するという処理を行う。
・トランザクションBは、データYを参照した後にデータXを参照するという処理を行う。

  • トランザクションAがデータX にアクセスし、ロックをかける。
  • トランザクションBがデータYにアクセスし、ロックをかける。
  • トランザクションAはデータYにアクセスしようとする(→ B のロック解除待ち)
  • トランザクションBはデータXにアクセスしようとする(→ A のロック解除待ち)

→ お互いに解除されないロックを待ち続ける状態になる。

さらっと学習【ロックの粒度】

ロックをかける対象データの大きさ(単位)のことを「ロックの粒度」といいます。粒度が細かいか粗いかによって、同時実行性と性能、管理コストのバランスが変わります。

・粒度が細かい→ロックの範囲が狭く、同時実行可能なトランザクションが増える

・粒度が粗い→ロックの範囲が広く、同時実行可能なトランザクションが減る

障害回復(リカバリ機能)

DBMSのリカバリ機能とは、障害(電源断、システムクラッシュ、ディスク障害など)からデータベースを正しい状態に戻す仕組みのことです。トランザクション処理における永続性(Durability)を保証するために必須の機能です。

ロールフォワード(フォワードリカバリ)

ロールフォワードとは、データベースの障害復旧処理において、更新後ログ(データの更新履歴)を使って、トランザクションを再適用し、最新の正しい状態に戻す操作のことです。バックアップファイル(またはチェックポイントファイル)と更新後ログを使って、コミット済みの処理を再実行することで、データベースは障害前と同じ状態に復元されます。

MEMO

ある時点でのデータベースの整合性が保証された状態(安全な状態)を記録する仕組みをチェックポイントと呼びます。ログファイル全体をスキャンせず、チェックポイント以降のログだけを使ってリカバリが可能になり、障害発生時のリカバリ時間を短縮できます。

ロールバック(バックワードリカバリ)

ロールバックとは、トランザクションの処理を途中で取り消して、データベースをトランザクション開始前の状態に戻す操作のことです。主に、トランザクションが途中で失敗したときやユーザーの明示的な中止操作に使われます。

確認○×問題

問1

表1と表2に、ある操作を行って表3が得られた。行った操作は「結合」と「選択」である。

答え:×

表1と表2から表3を得るための操作は次のようになります。

①まず、品名コードによって表1と表2を結合します。

品名コード品名価格メーカ棚番号
001ラーメン150A社1
002うどん130B社5

②次に、「品名」「価格」「棚番号」の列を抽出します(射影)。

品名価格棚番号
ラーメン1501
うどん1305

以上より、表1と表2から表3を得るための操作は「結合」と「射影」となります。なお、「選択」とは行(レコード)を抽出する操作です。

問2

関係データベースで管理している”入館履歴”表と”建物”表から、建物名が”東館”を条件に抽出した結果を日付の降順でソートしたとき、2番目のレコードの社員番号は「S0004」である。

答え:〇

正しい記述です。

建物名が”東館”の建物コードは「B002」なので、”入館履歴”表から建物コードがB002のレコードを抽出します。

社員番号建物コード日付
S0001B00210/30
S0002B00210/10
S0003B00210/12
S0004B00210/20

次に、日付の降順(大きい順)でソート(並び替え)します。

社員番号建物コード日付
S0001B00210/30
S0004B00210/20
S0003B00210/12
S0002B00210/10

以上より、2番目のレコードの社員番号は「S0004」となります。

問3

トランザクション処理に関する次の記述のうち、適切なものは2つある。

  1. コミットとは、トランザクションが正常に処理されなかったときに、データベースをトランザクション開始前の状態に戻すことである。
  2. 排他制御とは、トランザクションが正常に処理されたときに、データベースの内容を確定させることである。
  3. ロールバックとは、複数のトランザクションが同時に同一データを更新しようとしたときに、データの矛盾が起きないようにすることである。
  4. ログとは、データベースの更新履歴を記録したファイルのことである。

答え:×

  1. 誤り。記述はロールバックの説明です。
  2. 誤り。記述はコミットの説明です。
  3. 誤り。記述は排他制御の説明です。
  4. 正しい。

よって、適切な記述は4.の1つとなります。

問4

処理一覧に示す実行順に、トランザクション1〜4を実行する。あるトランザクションが途中で異常終了し、トランザクションを中断してロールバックした結果、データAとデータBが残った。異常終了したトランザクションは「トランザクション4」である。ここで、トランザクションが正常終了したときにコミットを行い、次のトランザクションがあれば、それを実行する。異常終了したときは、当該トランザクション以降のトランザクションを実行しないものとする。

答え:〇

正しい記述です。

各トランザクションが正常に終了したときのデータは次のようになります。

コミットされたトランザクション生成されたデータ
トランザクション1データA
トランザクション2データB
トランザクション3データA、データB
トランザクション4データA

ここで、ロールバックとはトランザクションの処理を途中で取り消して、データベースをトランザクション開始前の状態に戻す操作のことです。設問には「ロールバックした結果、データAとデータBが残った」とあるため、トランザクション4の処理が正常に終了しなかった(つまり、トランザクション4の処理開始前の状態に戻った)ということが分かります。

問5

複数のプロセスが共通の資源を排他的に利用する場合に、お互いに相手のプ口セスが占有している資源が解放されるのを待っている状態をデッドロックという。

答え:〇

正しい記述です。

ロック方式の課題(欠点)として、複数のトランザクションがお互いにロックの解除を待ち続けることで、永久に処理が進まなくなる状態になることがあります。この状態のことをデッドロックと呼びます。

問6

ある在庫管理システムは、複数の入力を同時並行して処理し、在庫数を更新しているが、排他制御は行っていない。ある時点での在庫数が100であったとき、入力された二つの入力A、Bに応じて、図に示す処理が①→②→③→④の順序で実行された場合、処理④が終了した時点の在庫数は「120」となる。

答え:×

処理①:入力Aによって在庫数が150(=初期値100+50)になります。

処理②:「複数の入力を同時並行して処理」しているため、入力Bが読み込んだ在庫数は初期値(更新前)の100です。ここから30を引くので在庫数は70となります。

処理③:入力Bで、70が在庫数として上書きされます。

処理④:入力Aで、150が在庫数として上書きされます。

以上より、処理④が終了した時点の在庫数は「150」となります。

このような結果となるのは、複数のユーザーが同時にデータベースにアクセス・操作したために、データの整合性や一貫性が壊れてしまうのが原因です。これを回避するためには排他制御を行います。

仮に、排他制御を行った場合は次のようになります。

処理①:入力Aによって在庫が150(=初期値100+50)になります。このとき、入力Aはロックをかけて入力Bが在庫数のデータにアクセスできないようにします。

処理②③:入力Bは在庫数のデータを参照できないため、ロックが解除されるまで待ちます。

処理④:入力Aでは、150が在庫数として書き込まれます。ここで参照が終わったのでロックを解除します。

処理②´:入力Bが読み込んだ在庫数は更新後の150です。ここから30を引くので在庫数は120となります。

処理③´:入力Bでは、120が在庫数として上書きされます

このように、排他制御を行うと処理がすべて終了した後の在庫数は120となり、期待通りの結果が得られます。