120

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 つの現象です。
ダーティ リード- ロック
なし Nonrepeatable Read - コミットされたデータのロックとしてのダーティ リードなし
ファントム リード- sql のブロック (select クエリを使用して選択される) のロック

これらの分離レベルを定義する場所を理解したい: jdbc/hibernate レベルまたは DB のみ

PS: Isolation levels in oracleのリンクを確認しましたが、不器用に見え、データベース固有の話をしています

4

3 に答える 3

10

brb tea が言うように、データベースの実装と使用するアルゴリズム (MVCC または Two Phase Locking) に依存します。

CUBRID (オープン ソース RDBMS)は、この 2 つのアルゴリズムの考え方を説明しています。

  • 二相ロック(2PL)

1 つ目は、T2 トランザクションが A レコードを変更しようとしたときです。T1 トランザクションが既に A レコードを変更していることを認識しており、T2 トランザクションは T1 トランザクションがコミットされるかロールされるかを認識できないため、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 トランザクションがロールバックされる場合、T1 トランザクション バージョンである 2 が A レコードに適用されなくてもかまいません。その後、T2 トランザクションがコミットされると、T2 トランザクション バージョンである 3 が 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:

    • READ_COMMITTED_SNAPSHOT が OFF に設定されている場合 (デフォルト): 共有ロックを使用して、現在のトランザクションが読み取り操作を実行している間、他のトランザクションが行を変更できないようにします。共有ロックは、他のトランザクションが完了するまで、ステートメントが他のトランザクションによって変更された行を読み取ることもブロックします。[...] 行ロックは、次の行が処理される前に解放されます。[...]
    • READ_COMMITTED_SNAPSHOT が ON に設定されている場合、データベース エンジンは行のバージョン管理を使用して、ステートメントの開始時に存在していたデータのトランザクション的に一貫性のあるスナップショットを各ステートメントに提示します。ロックは、他のトランザクションによる更新からデータを保護するために使用されません。
  • REPETEABLE_READ: 共有ロックは、トランザクション内の各ステートメントによって読み取られるすべてのデータに配置され、トランザクションが完了するまで保持されます。

  • SERIALIZABLE: 範囲ロックは、トランザクションで実行される各ステートメントの検索条件に一致するキー値の範囲に配置されます。[...] 範囲ロックは、トランザクションが完了するまで保持されます。

于 2016-01-26T17:18:59.540 に答える
5

ロックは常に DB レベルで行われます:-

Oracle の公式ドキュメント:- トランザクション中の競合を回避するために、DBMS はロックを使用します。これは、トランザクションによってアクセスされているデータへの他のユーザーによるアクセスをブロックするメカニズムです。(各ステートメントがトランザクションである自動コミット モードでは、ロックは 1 つのステートメントに対してのみ保持されることに注意してください。) ロックが設定されると、トランザクションがコミットまたはロールバックされるまで有効なままになります。たとえば、DBMS は、更新がコミットされるまでテーブルの行をロックできます。このロックの効果は、ユーザーがダーティ リード、つまり永続化される前に値を読み取ることを防止することです。(コミットされていない更新された値へのアクセスは、その値が以前の値にロールバックされる可能性があるため、ダーティ リードと見なされます。後でロールバックされる値を読み取ると、無効な値を読み取ったことになります。 )

ロックの設定方法は、トランザクション分離レベルと呼ばれるものによって決定されます。これは、トランザクションをまったくサポートしないものから、非常に厳密なアクセス ルールを適用するトランザクションをサポートするものまでさまざまです。

トランザクション分離レベルの 1 つの例は TRANSACTION_READ_COMMITTED です。これは、値がコミットされるまで値へのアクセスを許可しません。つまり、トランザクション分離レベルが TRANSACTION_READ_COMMITTED に設定されている場合、DBMS はダーティ リードの発生を許可しません。インターフェイス Connection には、JDBC で使用できるトランザクション分離レベルを表す 5 つの値が含まれています。

于 2015-08-04T19:49:54.367 に答える