私は約4レベルの分離を読みました。
Isolation Level Dirty Read Nonrepeatable Read Phantom Read
READ UNCOMMITTED Permitted Permitted Permitted
READ COMMITTED -- Permitted Permitted
REPEATABLE READ -- -- Permitted
SERIALIZABLE -- -- --
私は理解したい各トランザクション分離がテーブルに対して取るロック
READ UNCOMMITTED - no lock on table
READ COMMITTED - lock on committed data
REPEATABLE READ - lock on block of sql(which is selected by using select query)
SERIALIZABLE - lock on full table(on which Select query is fired)
以下は、トランザクションの分離で発生する可能性のある3つの現象です。
ダーティリード-ロックなし
繰り返し不可の読み取り -コミット済みデータのロックとしてダーティリードなし
ファントムリード -SQLのブロックをロック(選択クエリを使用して選択)
理解したいこれらの分離レベルを定義する場所:jdbc/hibernateレベルまたはDBでも
PS: Oracleの分離レベル のリンクを調べましたが、不格好に見え、データベース固有の話をします
私は理解したいです各トランザクション分離がテーブルで取るロック
たとえば、3つの並行プロセスA、B、Cがあります。Aはトランザクションを開始し、データを書き込み、コミット/ロールバックします(結果に応じて)。 BはSELECT
ステートメントを実行してデータを読み取ります。 Cはデータを読み取り、更新します。これらのプロセスはすべて同じテーブルTで機能します。
WHERE aField > 10 AND aField < 20
)でデータを読み取り、AがaField
値が10から20の間にデータを挿入し、その後Bがデータを再度読み取り、別の結果を取得することを意味します。これらの分離レベルを定義する場所を理解したい:JDBC/hibernateレベルまたはDBでも
JDBCを使用して、 Connection#setTransactionIsolation
を使用して定義します。
Hibernateの使用:
<property name="hibernate.connection.isolation">2</property>
どこ
Hibernate設定は here から取得されます(申し訳ありませんが、スペイン語です)。
ところで、RDBMSでも分離レベルを設定できます。
SET ISOLATION TO DIRTY READ
文について決して忘れません。)どんどん...
Brb teaが言うように、データベースの実装と使用するアルゴリズムに依存します:MVCCまたはTwo Phase Locking。
CUBRID(オープンソースRDBMS) 説明 この2つのアルゴリズムのアイデア:
- 二相ロック(2PL)
1つ目は、T2トランザクションがAレコードを変更しようとしたとき、T1トランザクションがすでにAレコードを変更したことを認識し、T1トランザクションがコミットされるかロールされるかをT2トランザクションが認識できないため、T1トランザクションが完了するまで待機する場合ですバック。この方法は、2フェーズロック(2PL)と呼ばれます。
- マルチバージョン同時実行制御(MVCC)
もう1つは、T1トランザクションとT2トランザクションのそれぞれに、独自の変更されたバージョンを持たせることです。 T1トランザクションがAレコードを1から2に変更した場合でも、T1トランザクションは元の値1をそのままにして、AレコードのT1トランザクションバージョンが2であると書き込みます。その後、次のT2トランザクションはAレコードを変更します2から4ではなく1から3で、AレコードのT2トランザクションバージョンは3であると書き込みます。
T1トランザクションがロールバックされるとき、2、T1トランザクションバージョンがAレコードに適用されなくてもかまいません。その後、T2トランザクションがコミットされると、3、T2トランザクションバージョンがAレコードに適用されます。 T1トランザクションがT2トランザクションの前にコミットされると、Aレコードは2に変更され、T2トランザクションのコミット時に3に変更されます。最終的なデータベースステータスは、他のトランザクションに影響を与えることなく、各トランザクションを個別に実行するステータスと同じです。したがって、ACIDプロパティを満たします。この方法は、マルチバージョン同時実行制御(MVCC)と呼ばれます。
MVCCは、メモリ内のオーバーヘッドの増加を犠牲にして同時変更を可能にします(同じデータの異なるバージョンを維持する必要があるため)および計算(REPETEABLE_READレベルでは、更新を失うことができないため、Hiberateなどのデータのバージョンをチェックする必要があります) Optimistick Locking )で行います。
2PLでは トランザクション分離レベルは以下を制御します :
データの読み取り時にロックを取得するかどうか、および要求するロックのタイプ。
読み取りロックが保持される期間。
別のトランザクションによって変更された行を参照する読み取り操作:
行の排他ロックが解放されるまでブロックします。
ステートメントまたはトランザクションが開始されたときに存在していたコミットされたバージョンの行を取得します。
コミットされていないデータ変更を読み取ります。
トランザクション分離レベルを選択しても、データ変更を保護するために取得されるロックには影響しません。トランザクションは、変更されたデータに対して常に排他ロックを取得し、そのトランザクションに設定された分離レベルに関係なく、トランザクションが完了するまでそのロックを保持します。読み取り操作の場合、トランザクション分離レベルは主に、他のトランザクションによる変更の影響からの保護レベルを定義します。
分離レベルを低くすると、多くのユーザーが同時にデータにアクセスできるようになりますが、ダーティリードやロストなどの並行処理効果の数が増えますユーザーが遭遇する可能性のある更新。
SQL Server のロックと分離レベルの関係の具体例(READ_COMMITTED_SNAPSHOT = ONのREAD_COMMITEDを除く2PLを使用)
READ_UNCOMMITED:共有ロックを発行して、他のトランザクションが現在のトランザクションによって読み取られたデータを変更できないようにします。 READ UNCOMMITTEDトランザクションは、現在のトランザクションが変更されたが他のトランザクションによってコミットされていない行を読み取ることを妨げる排他ロックによってもブロックされません。 [...]
READ_COMMITED:
REPETEABLE_READ:共有ロックは、トランザクション内の各ステートメントによって読み取られたすべてのデータに適用され、トランザクションが完了するまで保持されます。
直列化可能:範囲ロックは、トランザクションで実行される各ステートメントの検索条件に一致するキー値の範囲に配置されます。 [...]範囲ロックは、トランザクションが完了するまで保持されます。
ロックは常にDBレベルで取得されます。
Oracle公式ドキュメント:-トランザクション中の競合を回避するために、DBMSはロックを使用します。これは、トランザクションがアクセスしているデータへのアクセスをブロックするメカニズムです。 (各ステートメントがトランザクションである自動コミットモードでは、ロックは1つのステートメントに対してのみ保持されることに注意してください。)ロックが設定された後は、トランザクションがコミットまたはロールバックされるまで有効のままです。たとえば、DBMSは、更新がコミットされるまでテーブルの行をロックできます。このロックの効果は、ユーザーがダーティリードを取得できないようにすることです。つまり、値が永続的になる前に値を読み取ることです。 (コミットされていない更新された値へのアクセスは、その値が以前の値にロールバックされる可能性があるため、ダーティー読み取りと見なされます。後でロールバックされる値を読み取る場合、無効な値を読み取ります。 )
ロックの設定方法は、トランザクション分離レベルと呼ばれるものによって決まります。これは、トランザクションをまったくサポートしないことから、非常に厳しいアクセスルールを適用するトランザクションをサポートすることまでさまざまです。
トランザクション分離レベルの一例として、TRANSACTION_READ_COMMITTEDがあります。これは、コミットされるまで値へのアクセスを許可しません。つまり、トランザクション分離レベルがTRANSACTION_READ_COMMITTEDに設定されている場合、DBMSはダーティリードの発生を許可しません。インターフェイスConnectionには、JDBCで使用できるトランザクション分離レベルを表す5つの値が含まれています。