【Oracle】トランザクションとロックについて
はじめに
データベースはあらゆるシステムで重要な役割を担っています。ex)銀行システム、ECサイト等
これらのシステムにおいて何よりも求められるのがデータの正確性と整合性です。
本記事では銀行口座からお金を振り込む例をもとにトランザクションとロックの基本についてまとめます。
家賃を振り込む瞬間に障害発生🥲
あなたは銀行口座から家賃の10万円を大家に振り込もうとしています。送金を押した瞬間、障害が発生し振込ができませんでした。もし振込したはずのお金が口座から引かれてしまっていて、実際には口座にない事態が発生したらどうでしょうか?
このような事態を不整合と言います。
送金ができていないのだから、口座から引かれない状態が正ですよね。
このように、いかなる状況においてもデータベースのデータが常に正しい状態を保つことを「整合性」と言います。
こういった整合性を確実にする仕組みがトランザクションとロックです。
OracleDBを例に解説
トランザクションとは
複数の処理をまとめて、分割できない一つの論理的な処理単位として扱う機能を指します。
上記の例は2つの更新処理から構成されます。
- Aさん(自身)の口座から10万円を引き算する更新処理
- 大家の口座に10万円を足し算する更新処理
もしAさんの口座から引き算をし、大家の口座に足し算をする前に何らかの障害が発生したらどうなるでしょうか?
トランザクションがなければAさんの口座から減った10万円は、大家の口座に加算されないまま消滅する可能性があります。
このような事態を防ぐため、トランザクションは以下のどちらかの状態を必ず保証します。
- 全ての処理が正常に実行を完了する(成功)
- 途中でエラーが起きた場合、全ての処理が取り消される(失敗)
つまり10万円の引き算と足し算を入金の一連の処理として一つの塊として扱います。途中でエラーが発生した場合すべての処理をなかったことにします。このように複数の処理をまとめて扱う機能をトランザクションと呼びます。
コミットとロールバック
データベースではトランザクションの結果を反映させるためにコミットという処理が必要になります。変更を確定するイメージです。
逆にトランザクション中の処理を破棄し、データベースをトランザクション開始前の状態に戻すことをロールバックと呼びます。
多くのRDBではDML文であるINSERT、UPDATE、DELETEを実行しても、その変更はすぐに他のユーザーから見えるわけではありません。一時的に変更が行われた状態にあるので、コミットをして初めて他のユーザーからも参照することが出来るようになります。
もし複数のユーザーが同じタイミングでDML分を実行したら?
AさんがDML文を実行した直後にBさんもDML文を実行したと想定します。
その場合Aさんが変更を加えたレコードにロックがかかります。つまりAさんがコミットorロールバックを行うまでBさんは同じレコードに変更を加えることが出来なくなります。
このようにレコード単位で操作を制限する機能を行レベルロックと言います。
Bさんの変更は保留されている状態でAさんがコミットorロールバックを行うと反映されます。
このようにロックがされることによってAさんがUPDATEをしてもBさんのSELECT結果に影響が出ないことを読み取り一貫性と呼びます。
※Aさんがコミットorロールバックを行うことで初めてBさんのSELECT結果が変わります。
この読み取り一貫性は、Oracleデータベースがサービスリリース当初から持つ強力なメリットであり、高い信頼性を実現する基盤となっています。銀行システムのように信用が重要なシステムに採用がされる傾向にあるそうです。
単語まとめ
データベース: 銀行システムやECサイトなど、あらゆるシステムでデータの管理に重要な役割を担うシステムです。
整合性: いかなる状況においてもデータベースのデータが常に正しい状態を保つことです。
トランザクション: 複数の処理をまとめて、分割できない一つの論理的な処理単位として扱う機能です。途中でエラーが起きた場合は全ての処理が取り消され、データの整合性を保証します。
ロック: 複数のユーザーが同じデータに同時にアクセスした際、データの変更を一時的に制限し、整合性を保つための仕組みです。
コミット: トランザクション中の変更をデータベースに反映させ、確定・永続化させる処理です。
ロールバック: トランザクション中の変更を破棄し、データベースをトランザクション開始前の状態に戻す処理です。
DML文: データベースのデータを操作するためのSQL文です(例: INSERT, UPDATE, DELETE)
INSERT: データベースのテーブルに新しいデータを追加する
UPDATE: データベースのテーブルの既存のデータを更新する
DELETE: データベースのテーブルから既存のデータを削除する
RDB (リレーショナルデータベース): テーブル(表)形式でデータを管理するデータベースの一種
レコード: データベースのテーブルにおける1行分のデータの単位
行レベルロック: データベースのテーブルの特定のレコード(行)単位で、他のトランザクションからの変更を制限するロック機能
読み取り一貫性: あるユーザーがデータを読み取っている最中に他のユーザーがそのデータを更新しても、読み取り側のユーザーがその更新の影響を受けず、常に整合性のあるデータを参照できるOracleデータベースの特性です。
Discussion