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やデータベースについてもっと学びたい方は次の記事でおすすめの書籍を紹介しています↓
はじめに
A01_はじめに
A02_コースの概要
Type
B01_Typeクラスとは
B02_型からTypeを取得する
B03_自前の型からTypeを取得する
B04_インスタンスからTypeを取得する
B05_Typeのインスタンスは1つだけ
Assembly
C01_Assemblyとは
C02_Assemblyの生成_実行中のアセンブリを取得
C03_Assemblyの生成_アセンブリ名で取得
C04_Assemblyの生成_パスを指定して取得
C05_Assemblyの生成_呼び出し元を取得
C06_Assemblyの生成_型から取得
C07_すべての型を取得する
C08_publicな型だけを取得する
C09_名前を指定して型を取得する
C10_メタ情報の取得
インスタンスの生成
D01_インスタンスの生成
D02_インスタンス生成後の具体例
D03_空のコンストラクタがないとエラーになる
D04_Activatorを使ったインスタンスの生成
D05_引数ありのコンストラクタで生成する方法
ConstructorInfo
E01_コンストラクタの情報を取得
E02_パラメータの情報を取得
E03_コンストラクタの情報からインスタンスを生成する
E04_コンストラクタを検索して生成する
E05_public以外のコンストラクタを取得
E06_staticなコンストラクタがある場合の注意点
E07_コンストラクタのアクセスレベルを取得する
MethodInfo
F01_MethodInfo
F02_引数ありのメソッド呼び出し
F03_メソッドがオーバーロードされているときの指定方法
F04_GetMethods
F05_属性で取得する
F06_staticメソッドを呼び出す
F07_戻り値を取得する
PropertyInfo
G01_PropertyInfo
G02_GetProperties
G03_属性を使ったチェック
G04_汎用的なチェックメソッド
G05_CanWrite
FieldInfo
H01_FieldInfo
H02_public以外のFieldInfo
EventInfo
J01_EventInfoとは
J02_AddEventHandler
J03_EventInfoの注意点
J04_RemoveEventHandler
dynamicを利用したリフレクション
K01_dynamicを利用したリフレクション
K02_dynamicを利用したメソッドの呼び方
K03_オーバーライドされたメソッドの呼び出し
K04_メソッドの存在チェック
K05_dynamicを利用したプロパティへのアクセス
K06_dynamicを利用したフィールドへのアクセス
K07_dynamicを利用したイベントへのアクセス