トランザクションの行方
私は現在 IPA の国家試験 データベーススペシャリストの勉強中です。
勉強しているうちにトランザクションを語りたくなったので書いてみました。
RDBMS(リレーショナルデータベースマネジメントシステム)
データを保存するための入れ物であるデータベース。
その種類のなかに RDBMS(リレーショナルデータベースマネジメントシステム)というものがあります。
MySQL,PostgreSQL,Oracle なんかが有名です。
RDBMS の基本構造
一般的な RDBMS でデータを取得する手順は以下の通りです。
- クライアントプログラムがどんなデータ取得したいのかをRDBMS に伝えます
- RDBMSはストレージ(ファイル)から目的のデータを探し出します
- RDBMS はクライアントプログラムにデータを返します
上記の手順 1 でどんなデータが取得したいのか(もっというと RDBMS に何をして欲しいのか)を伝えるための言語がSQLです。
トランザクション
トランザクションの役目
RDBMS は中途半端にデータが更新されることが絶対に怒らないように実装されています。
例えば、以下のような銀行のシステムの送金処理を考えてみます。
Aの残高を減らす
Bの残高を増やす
このような処理において 「A の残高を減ら」 した後、B の残高を増やす 前に 何らかのエラーで B の残高を増やせなかったとしたらどうなるでしょう?
A の口座からは残高が減りましたがB の口座に送れていません。
エラーが起きたからといってこんなことが起きてしまったら口座の金額が合わなくなってしまいます。
これを解決するためには
もし処理の途中でエラーが発生してしまったら「A の残高を減らす」処理もなかったことにして欲しい (=エラーが発生したら A の残高を減らさないでほしい)
これを叶える RDBMS の機能がトランザクションです。
トランザクションを利用する
トランザクションではSQL の複数行を 1 つにまとめて扱うようにします。
送金処理トランザクション はじめ
Aの残高を減らす
Bの残高を増やす
送金処理トランザクション 終わり
RDBMS は SQL 文がトランザクションでまとめられている時にトランザクション実行中にエラーが発生したらそのトランザクションごと実行しなかったことにしてくれます。
トランザクションの行方
このようにトランザクションで処理をまとめることで途中でエラーが発生しても中途半端なデータを作らないことができるようになります。
よってトランザクションは以下のように動作します。
- トランザクション内の処理を実行します
- 途中でエラーが発生したら元にもどす
- 成功したら更新結果を DB に反映する
ここで
- 2.で元に戻すことを ロールバック と言います。
- 3.で更新結果を DB に反映することを コミット と言います。
つまりトランザクションには 成功してコミット するか 失敗してロールバック するかの 2 つの未来が待っています。
また、SQL で書いてみると次のようになります。
送金処理トランザクション はじめ
Aの残高を減らす
Bの残高を増やす
コミット または ロールバック
// 1. トランザクションのはじめ
BEGIN;
// 2. トランザクションの内容
INSERT INTO ...
DELETE FROM ...
// 3. 成功または失敗
COMMIT; // コミット
ROLLBACK; // ロールバック
Discussion