📗

SQL-トランザクションについてまとめ(基礎)

2023/06/17に公開

トランザクションを学習する

こんにちは!わいわわです。
最近はSQLやデータベースについて、基礎の部分を学習しています。
今回はトランザクションとその関連用語について、まとめていきます!

トランザクション

データベースに対して行われる複数の処理をまとめたものをトランザクションといいます。
SQLは1文ずつ実行することができますが、連続して複数のデータの追加や更新の必要がある場合は
1つのアクションとして実行するように一連の処理を束ねることができます。

例)
1.○○レコードを更新
2.××レコードを更新
3.△テーブルにレコードを追加

なぜトランザクションがあるのか

A口座からB口座に10万円を送金するシチュエーションを例に考えていきます。
・A口座の預金をマイナス10万円にする
・B口座の預金をプラス10万円にする
という2つの処理が必要ですが、
もしA口座の処理が完了した直後にシステム問題が発生し、
B口座の処理が実行されないと送金額が反映されなくなってしまう、
ということが起きてしまうため、トランザクションで防いでいるんですね!

トランザクションの特徴

・原子性
トランザクションに含まれる処理が「すべて実行される」か「すべて実行されない」のどちらかになる
・一貫性
あらかじめ設定された条件を満たし、データの整合性を保証する
・独立性
処理の途中経過が隠蔽され、外部からは結果だけ見ることができる
処理の実行途中の状態で、他の処理に影響を与えない
・永続性
トランザクションが完了したら、その結果が失われることはない

コミット

コミット...トランザクション処理を確定する
一連のトランザクションに含まれる処理が成功した時に
その結果をデータベースに反映させることをコミットと呼びます。
トランザクションを用いた場合、SQL文を実行する過程ではまだデータベースには結果が反映されていません。
最後にコミットを行うことで、そこで初めて変更内容が適用されます。

流れを改めて記述します!
 
トランザクション開始
 ↓
○○レコードを更新
 ↓
××レコードを更新
 ↓
△テーブルにレコードを追加
 ↓
コミット

コミットを行うまでは、トランザクション内のコマンド実行中の値は他の処理から見えません。

実行コマンド

トランザクションの実行方法はデータベース管理システムによって違いがあります。
MySQLの場合はSTART TRANSACTION;を実行し、その後に処理を書いていきます。
最後に、COMMIT;というコマンドを実行することでコミットを行うことができ、
データベースに変更内容が適用された状態となります。

ロールバック

トランザクション内の処理で問題が発生した時に、
処理を取り消してトランザクション開始時点の状態まで戻すことをロールバックと呼びます。
データベース上で実行される処理は常に正常に行われるとは限りません。
バグやネットワーク障害によってデータベースに接続できなくなるなど、
そのようなときにトランザクション内の処理を途中で中断してしまうと、
データの整合性がとれなくなってしまうことがあります。
これを防ぐためにロールバックがあり、
トランザクション内の処理を取り消し、整合性が保たれた状態まで復旧します。
そのあため、データベース上での変化はありません。

実行コマンド

こちらもデータベース管理システムによって違いがありますが、
MySQLの場合はSTART TRANSACTION;と実行したい処理を書き、
もし問題が発生した場合はROLLBACK;を実行することで
トランザクション内の処理を巻き戻すことができます。

デッドロック

複数のトランザクション処理が同時に同じデータを操作することで、
互いに相手の処理終了を待つ気状態となり、次の処理へ進めなくなってしまうことがあります。
これをデッドロックといいます。

銀行口座の例で考えていきます。
A口座とB口座に10万円ずつはいっている状態で
1.A口座からB口座に10万円を送金するアクション
2.B口座からA口座に10万円を送金するアクション
のやり取りが同時に行われたとします。

まず、1つ目のやり取りの「A口座の預金を-10万円する」という処理が実行されると
コミットが行われるまでA口座のデータはロックされた状態となります。
このようにトランザクション中の処理に係るデータは一時的にロックされます。
もし、他の処理がロック状態のデータを操作しようとした場合は、
ロックが解除されるまで待ってから処理が実行されます。

2つ目のやり取りの「B口座の預金をー10万円する」という処理も実行されます。
同様にして、B口座のデータがロックされます。
すると、2つのトランザクションがお互いに相手が操作したいデータをロックしていて処理を進められず、
どちらのアクションも止まってしまいます。
これがデッドロックです。

デッドロックの対策

デッドロックが起こった場合、どちらか片方の処理を終了させなければいけません。
データベース管理システムによっては自動的にデッドロックを監視し、
ロールバックを行う仕組みもあります。が、発生させないことが大事です。
例として
・トランザクション内の処理時間を短くする
・トランザクションからアクセスするデータの順番を統一する
等の対策が考えられます。

口座間の送金の例でいうと、
どちらのトランザクションもA口座のデータ更新後にB口座のデータを更新すれば、デッドロックを回避できます。

所感

今回はトランザクションやロールバック、デッドロックなどの用語を学習しました。
どのデータベース管理システムでも使う汎用性の高い用語や知識なので
復習して使いこなせるようにしていきたいです!

Discussion