データベース・トランザクション、ロック


トランザクションフィーチャー


第一に、原子性、すなわち不可分性;第二に、一致性、データ更新前後と業務の一致性を保証する.第三に、隔離性、複数の事務は影響しない.第四に、永続性、トランザクションのコミット後、データは永続的にヘテロデータベースに格納されます.

独立性レベル


コミットされていないトランザクションを読み込み変更または新規作成すると、前のトランザクションがコミットされていないデータを読み込むことができ、ダーティリードが生成されます.読み取りコミット(oracleデフォルトの独立性レベル)1つのトランザクションが変更または追加された後、コミットされていない場合、別のトランザクションは読み取りできません.コミットされたトランザクションのデータのみを読み込むことができます.2回連続して読み取ると、1回目のデータが2回目のデータの中で多かれ少なかれ読み返されない場合があります.繰り返し読み込み(MySQLのデフォルトのトランザクション独立性レベル)1つのトランザクションは読み込み中であり、もう1つのトランザクションは書き込めません.幻読みになるかもしれません.シーケンス化各行について、1つのトランザクションは読み取り中であり、もう1つのトランザクションは読み取りまたは書き込みできません.

汚い読み、繰り返してはいけない読み、幻読みの意味


ダーティリード:あるトランザクションは、別のトランザクションがコミットしていないデータを読み込むことができます.
繰り返し不可:1つのトランザクションで異なる期間のクエリに異なる結果が表示され、更新によって削除される可能性があります.
幻読み:1つのトランザクションで異なる期間にクエリーされ、レコード数が異なります.再読み込み不可との違いは、幻読みではすでに読み込まれたデータは変更されませんが、以前に比べてクエリー条件を満たすデータが多くなります.
Oracleデータベースでは、READ COMMITTEDとSERIALIZABLEの2つのトランザクション独立性レベルがサポートされています.

ロック


データベースの大規模な同時操作は、デッドロックとロックのパフォーマンスの問題を考慮します.データベース・システムのACIDプロパティでは、データベース・システムが同時に実行される各トランザクションを分離する能力を有し、相互に影響を及ぼさないようにする必要があることを意味します.データベースはロックを使用してトランザクションの独立性を実現します.ロックの基本原理は、1、トランザクションがデータベース・リソースにアクセスする場合、select文を実行するには共有ロックを取得する必要があり、insert、update、delete文を実行する場合は、操作されたリソースをロックするために独占ロックを取得する必要があります.2、2番目のトランザクションが同じリソースにアクセスする場合、対応する文もまず対応するロックを取得する必要があります.この場合、状況に応じて2番目のトランザクションがロックを待機するか、すぐにロックを取得できるかを決定できます.

ロックの基本種類


行レベルロック


行レベルのロックは排他的なロックであり、他のトランザクションがこの行を変更することを防止します.次の文を使用すると、Oracleでは行ロックが自動的に適用されます.
INSERTUPDATEDELETESELECTFOR UPDATE [OF columns] [WAIT n | NOWAIT];

SELECT…FOR UPDATE文は、ユーザーが一度に複数のレコードをロックして更新することを許可するCOMMIT文またはROLLBACK文を使用してロックを解除する

テーブルレベルロック

  • 共有ロック
  • 複数のユーザーが同じテーブルに同時にこのロックを適用できるように、レコードに対して読み取り専用で書き込みを行わないテーブルをロックします.
    T1:  select * from table
    T2:  update table set column1='hello'
    
      : T1   (    ) T2   If T1       T2 ...... else      T2   endif

    T 2が待つのは、T 2がupdateを実行する前にtableテーブルに排他ロックを追加しようとしたためであり、データベースは同じリソース上で共有ロックと排他ロックを同時に共存できないことを規定している.したがって、T 2は、T 1の実行が完了し、共有ロックが解放されてから、update文の実行が開始されるまで、排他ロックを追加する必要があります.
    T1:    select * from table T2: select * from table   T2    T1   ,        。   : T1  , table   ,   lockA T2  ,  table      ,   lockB。

    2つのロックは、同じテーブルなど、同じリソースに同時に存在することができます.これは共有ロックと共有ロックの互換性と呼ばれます.これは、共有ロックは他のセッションがリソースを同時に読むことを阻止しないが、他のセッションupdateを阻止することを意味する.
    T1:    select * from table T2: select * from table T3: update table set column1='hello'

    今回、T 2はT 1が完了するのを待たずに実行できますが、T 3はT 1とT 2が完了するのを待たなければ実行できません.T 3はT 1とT 2の共有ロックがすべて解放されるまで待たなければならないので、排他ロックを行ってupdate操作を実行することができない.
  • 更新ロック共有ロックはデッドロックを引き起こすので、更新ロック
  • を導入する.
    T1:
    begin tran select * from table(updlock) (    ) update table set column1='hello' T2: begin tran select * from table(updlock) update table set column1='world'

    更新ロックとは、「私は今読みたいだけです.他の人も読むことができますが、将来更新操作をする可能性があります.共有ロックから排他ロック(更新用)までの資格を取得しました」という意味です.トランザクションには更新ロックが1つしかありません.
    T 1はselectを実行し、更新ロックを加える.T 2は運行して、更新ロックを加えるつもりですが、すでに1つの更新ロックがそこにあることに気づいて、待つしかありません.
    後でuser 3、user 4...tableテーブルのデータをクエリーする必要がある場合、T 1のselectが実行されているためブロックされることはなく、クエリーすることができます.更新ロックは共有ロックと共存できます.
  • 排他ロック(排他ロック、Exclusive Locks)
  • 他のトランザクションは読み取りもできないし、ロックされたリソースを並べ替えることもできません.
    T1:    update table set column1='hello' where id<1000 T2: update table set column1='world' where id>1000   T1  ,T2   ,     T1  id<1000        .     T2 update。   id          T1: update table set column1='hello' where id<1000 T2: update table set column1='world' where id>900

    T 1先達、T 2はすぐに到着し、T 1に加えられた排他ロックはT 2のupdateをブロックする.
  • 意向ロック(Intent Locks)
  • 意向ロックとは、部屋(例えば表を表す)の入り口に標識を設置し、部屋に誰か(例えば記録を表す)がロックされていることを意味します.もう一人は部屋に鍵をかけられている人がいるかどうか知りたいので、部屋に入って一つ一つ調べなくても、入り口の標識を直接見ればいいです.
    テーブルの行に排他ロックが付加されると、テーブルはロックされません.データベース・プログラムは、テーブルがロックされていないことをどのように知っていますか?1つの方法は、テーブルの各レコードに排他ロックがあるかどうかを1つずつ判断することであり、もう1つの方法は、テーブルという階層でテーブル自体に意向ロックがあるかどうかを直接チェックし、1つずつ判断する必要はありません.明らかに後者は効率が高い.
    T1:    begin tran select * from table (xlock) where id=10 --    id=10         T2: begin tran select * from table (tablock) --        

    仮にT 1が先に実行され、T 2が実行され、T 2が実行されると、テーブルロックを追加しようとすると、テーブルロックを追加できるかどうかを判断するために、データベースシステムはtableテーブルの各行の記録に排他ロックがあるかどうかを1つずつ判断し、そのうちの1行に排他ロックがあることが発見された場合、テーブルロックを追加することは許されない.ただ、このように一つ一つ判断するのは効率が低すぎる.
    実際、データベースシステムはこのように動作しません.T 1のselectが実行されると、システムはテーブルtableのid=10のこの行に排他ロックを追加し、同時にこっそりテーブル全体に意向排他ロック(IX)を追加し、T 2がテーブルロックを実行すると、このテーブルがすでに意図排他ロックが存在していることを見るだけで、リソースを逐条検査する必要はありません.
    T1:    begin tran update table set column1='hello' where id=1 T2: begin tran update table set column1='world' where id=1

    この例は上記の例と実際の効果は同じで、T 1は実行して、システムはtableに対して同時に専門家に対して他のロックを並べて、ページに対して意向を加えて他のロックを並べて、表に対して意向を加えて他のロックを並べます.
  • 計画ロック(Schema Locks)
  • alter table …. (schema locksを加え、Schema modification(Sch-M)locksと呼ぶ
    DDL文にはSch-Mロックが追加されます.このロックでは、他のセッションがテーブルに接続できません.このテーブルにもつながっていません.もちろん、このテーブルに対して何のsql文を実行したいのかは言うまでもありません.
    jdbcでデータベースに新しいsql文を送信しました.データベースはまずそれをコンパイルし、コンパイル中にもロックをかけます.Schema stability(Sch-S)locksと呼ばれています.
    select * from tableA

    この文のコンパイル中、他のセッションはテーブルtableAに対して任意の操作(update、delete、排他ロックなど)を行うことができますが、DDL(alter tableなど)操作はできません.

    楽観ロックと悲観ロック


    この2つのロックはアプリケーションで実現され、データベースの下部にはこの2つの機能がありません.主にプログラムの同時性を高めるためです.
  • 悲観ロック
  • データベース自体のロックメカニズムを利用して実現します.上記のデータベース・ロックの理解により、トランザクション・アイソレーション・レベルと、ロックの粒度を低減するなど、合理的な手動指定ロックの方法を、特定のビジネス状況に応じて総合的に使用して同時待機を低減できます.
  • 楽観ロック
  • プログラム処理による同時処理.原理はすべて比較的によく理解して、基本的に見るとすぐわかります.方式は,更新するデータを記録にバージョン番号を付けて記録にタイムスタンプを付けて事前に読み取り,事後比較する3種類程度である.
    悲観的なロックとは、データベース・メカニズムに基づいて実現されます.たとえばselect句を使用するときにfor updateを付けると、句を変更するトランザクションが終了するまで、どのアプリケーションもselectからのレコードを変更できません.
    楽観的ロックとは、アプリケーションのバージョンメカニズムに基づいて実現される.通常、テーブルにバージョンフィールドvが設計されます(通常、このフィールドをtimestampに設定します).一般的なupdateシーンは次のとおりです.
    select a, v from tb where id=1;   
    
           :['xxx', 11111]
    update tb set a='yyyy', v=systimestamp where v=11111; 
    //  , v              

    これは、update操作のたびにバージョンフィールドを変更する必要があります.そうしないと、プロセス間のデータが上書きされます.
    楽観的なロックでは、他のアプリケーションのデータに対する操作をロックできません.楽観ロックと悲観ロック