ITパスポート対策
トランザクション
データベースは複数の人が同時に使います。同時に使っても壊れないようにするしくみが、トランザクションと排他制御です。
トランザクションはまとめて1つの処理
銀行の振込を考えます。A口座から1万円を引き、B口座に1万円を足す。この2つは片方だけ終わってはいけません。引いた直後にシステムが止まれば、1万円がこの世から消えます。
そこで、切り離せない一連の処理をひとまとまりとして扱います。これがトランザクションです。全部成功したらその結果を確定させ、これをコミットといいます。途中で失敗したら開始前の状態に戻し、これをロールバックといいます。中途半端な状態で終わることはありません。
ACID特性
トランザクションが満たすべき4つの性質をACID特性といいます。頭文字の並びで覚えます。
| 性質 | 英語 | 意味 |
|---|---|---|
| 原子性 | Atomicity | 全部実行されるか、まったく実行されないかのどちらか |
| 一貫性 | Consistency | 実行の前後で、決められた整合性が保たれる |
| 独立性 | Isolation | 同時に動く他の処理から影響を受けない |
| 耐久性 | Durability | いったんコミットした結果は障害が起きても失われない |
試験では性質の名前と説明文の組み合わせを入れ替えてきます。とくに紛らわしいのが原子性と耐久性です。「途中で終わらせない」が原子性、「終わったものを消さない」が耐久性です。処理中の話か、処理後の話かで見分けます。独立性は隔離性ともいい、同時実行しても1件ずつ順に実行したのと同じ結果になる、という言い方で出ます。
同時更新で起きる事故
排他制御がないと何が起きるか、在庫数が10の商品で見てみます。
- 処理Aが在庫数10を読む
- 処理Bも在庫数10を読む
- 処理Aが3個売れたので7を書き込む
- 処理Bが2個売れたので8を書き込む
本当は5個売れたので在庫は5のはずですが、結果は8になりました。処理Aの更新が処理Bに上書きされて消えています。これを更新の消失といいます。
これを防ぐのが排他制御です。あるトランザクションがデータを使っている間、そのデータに鍵をかけて他のトランザクションを待たせます。この鍵がロックです。処理Aがロックを取っている間、処理Bは読むところから待たされるので、10を読んで7になった後に処理Bが動き、正しく5になります。
ロックには2種類あります。読むだけなら他の人も同時に読んでよい共有ロック、書き込むときは他の誰にもさわらせない専有ロックです。読み手どうしは共存できるが、書き手がいるときは誰も入れない、という関係です。
デッドロック
ロックには副作用があります。処理Aが商品表をロックしたまま在庫表を待ち、同時に処理Bが在庫表をロックしたまま商品表を待つと、お互いが相手の解放を待ち続けて永久に進みません。これがデッドロックです。
対策は、資源をロックする順番を全部の処理でそろえることです。必ず商品表、次に在庫表、と決めておけば、待ちが一方向になるのでにらみ合いになりません。DBMS側でデッドロックを検知し、片方のトランザクションを強制的にロールバックして解消する方式もあります。
試験ではデッドロックの説明として「処理が終わらず互いに待ち続ける状態」が正解文になり、「ロックのかけすぎで性能が落ちること」や「更新が上書きされて消えること」が誤りの選択肢として並びます。更新の消失はロックが無いときの事故、デッドロックはロックが有るからこそ起きる事故です。ここを逆にしないでください。