ACIDのIに注目
ACIDのIとはIsolation「独立性」です。
トランザクションが他の
トランザクションの影響を受けない
という特性の事です。
ダーティーリードとかファントムリードのお話です。
トランザクションが他のトランザクションの影響を受けないようにするには?
同じ資源を更新する2つのトランザクションを
同時,並列に実行すると干渉しあってしまいます。
例えば,口座の残高照会5万円に対して金額をプラス1万円の処理と
給料の入金20万円の処理が同時に実行された場合,
残高照会5万円とプラス1万円の間で
給料のプラス20万円が実行されたら,
本来25万円に対してプラス1万円で26万円となるところが,
5万円にプラス1万円して6万円になってしまったら
とんでもない話ですよね。
DBMSでは,そんなことにならないような
工夫がされています。
トランザクション同士が干渉しなくするには
基本的にはロックをかける必要があります。
先の例でも,プラス1万円とプラス20万円が
直列で順番に処理されていれば26万円になっていたはずです。
だから,並列処理を直列にすればすべては解決します。
しかし,日々大量おトランザクションがある中で
誰かが使っている時間は使えないってなると
困ってしまいますよね。
この状態をスループットが低下しているいいます。
どこまで許容して並列実行させるか
すべて直列にすれば解決するけど
スループットが低下する。
だからどこまで許容しようかって話になります。
分離レベル
その許容はレベル分けされて整理されています。
レベル0
READ UNCOMMITTED
レベル1
READ COMMITTED
レベル2
REPEATABLE READ
レベル3
SERIALIZABLE(シリアライザブル)直列可能の意味
レベルが上がるほど不整合は防げるスループットは下がる
ダーティーリード
直訳:汚染された情報を読んでしまう
意味:相手がcommit/rollbackする前のデータを参照する
他のトランザクションがコミット前の情報を読み込んでしまう。
そのままコミットされれば問題ないが
ロールバックされた場合は,存在しない値で処理したことになる。
例)T1がと商品代金を100からをから200に変更(コミット前),
T2が商品代金を検索すると200が取得される。
その後T1がロールバックされ,商品代金は再び100になる。
これだと商品代金200って一度も
世の中に出ていない値でT2は何らかの処理を
したことになってしまいます。
ノンリピータブルリード
同じ条件で検索しても異なった結果が返却される
一つのトランザクション(T1)のなかで
何かしらループ処理をしていて,
最初に検索した商品代金は100円だったのに
途中から200円になる感じ。
原因は他のトランザクション(T2)が200円にしてコミットしたから。
この場合,T1の処理が終わってから
商品代金がT2によって書き換えられれば
問題ないが,
T1の同一トランザクションのなかで
検索するたびに値が変わってしまうと
バグの原因となる。
ファジーリードとも言う。
ファントムリード
幻影が見える
突然値が発生したように見える
これは先のノンリピータブルリードのレコード版です。
先ほどはループ中に値が変更されましたが,
行が追加されてしまうのが
ファントムリードです。
ロストアップデート
これまで見てきたような
排他処理を全く行わない場合は
データを消失する可能性がある。
例えばサーバー上のエクセルファイルを
ローカルPCにコピーし,
編集する。
再びそのファイルをサーバー上にコピーした場合,
最初にコピーして編集している間に
誰かがそのサーバーのファイルを
更新していた場合は,その更新をすべて
無きものにしてしまいますよね?
そのためサーバー上のファイルを開いているときは
誰かが開いているときは読み取り専用でしか
開けないようになっています。
こういった更新データを無きものにすることを
ロストアップデートといいます。
SQLやデータベースについてもっと学びたい方は次の記事でおすすめの書籍を紹介しています↓
#01_はじめに
#02_VisualStudio2022のインストール
#03_SQLServerのインストール
#04_データベースとテーブルの作成
#05_プロジェクトの作成
#06_接続先文字列の作成
#07_データテーブルでのデータの取得
#08_Sqlアクセスクラスの作成
#09_SqlDataReaderでのデータ取得
#10_SqlDataReaderの結果をカスタムクラスに入れる方法
#11_SqlCommandでInsert文を発行する方法
#12_SqlCommandでUpdate文を発行する方法
#13_Update対象がなかったらInsertする方法
#14_SqlCommandでDelete文を発行する方法
#15_Dapperでデータを取得する方法
#16_DapperでInsert文を発行する方法
#17_EntityFrameworkをインストールしてDbContextを作成する方法
#18_EntityFrameworkでデータを取得する方法
#19_EntityFrameworkでInsert文を発行する方法
#20_EntityFrameworkでUpdate文を発行する方法
#21_EntityFrameworkでDelete文を発行する方法
#22_Helperクラスを作ってSqlCommand操作を共通化する方法
#23_パフォーマンスチェックの方法
#24_4つのデータのとり方のパフォーマンスチェック
#25_4つの結果を踏まえて講評
#26_さいごに
下記URLは、ベネッセが提供する教育用プラットフォームにて
私が公開しているプログラミング学習コースです。
無料コースもあるので、よかったらご覧になってみてください。
【無料動画】「C#を勉強する順番」