どうきせいぎょ


同時制御は、データベースが同時に実行される複数のトランザクションの相互干渉から保護される必要があることを意味します.
同期性を向上させるためにロックの使用を最小限に抑えることは、一貫性を保つことが困難であり、一貫性を向上させるためにロックを積極的に使用すると、同期性が低下する.
->同期制御の目的は、データの入力、変更、削除、および取得時に同時に実行されるトランザクション数を最小限に抑えることです.

どうきせいぎょぎじゅつ


悲観的な同期制御


ユーザーが同じデータを同時に変更すると仮定します.したがって、クエリーまたは更新処理が完了するまで、1人のユーザがデータを読み出すときにロックされます.
for update nowait:ロックされていない場合は、待たずにExceptionを放出
for udpate wait 3:3秒以内にロックが取得されない場合はException(待機なし)を投げ出す
waitまたはnowaitオプションを使用してトランザクションを終了すると、同期性が増加する可能性があります.

楽観的な同期制御


ユーザーが同じデータを同時に変更しないと仮定します.したがって、データの読み込み時にはロックされません.ただし、変更時には、値が他のユーザーによって変更されているかどうかを確認する必要があります.
sql%rowcount:最近実行されたSQL文が影響する行数
select 적립포인트, 방문횟수, 최근방문일시, 구매실적 into :a, :b, :c, :d
from 고객
where 고객번호 = :cust_num;

update 고객 set 적립포인트 = :적립포인트
where 고객번호 = :cust_num
and 적립포인트 = :a
and 방문횟수 = :b
and 최근방문일시 = :c
and 구매실절 = :d;

if sql%rowcount = 0 then
	alert('다른 사용자에 의해 변경되었습니다.');
end if;
selectセクションで読み込まれるカラム数が多い場合、update時にwhereセクションに書き込む条件が多くなります.updateターゲットテーブルに最終変更時間列がある場合は、レコードを更新するかどうかをより簡単に判断できます.
select 적립포인트, 방문횟수, 최근방문일시, 구매실적, 변경일시 into :a, :b, :c, :d, :mod_dt
from 고객
where 고객번호 = :cust_num;

update 고객 set 적립포인트 = :적립포인트, 변경일시 = SYSDATE
where 고객번호 = :cust_num
and 변경일시 = :mod_dt;

if sql%rowcount = 0 then
	alert('다른 사용자에 의해 변경되었습니다.');
end if;

マルチバージョン同時制御


同期制御の目的は、入力、変更、削除、および取得時に同時に実行されるトランザクションの数を最小限に抑え、データの整合性を維持することです.しかしながら、一般的なロックメカニズムでは、読み書き操作が互いに干渉し、同期性の問題を招くことが多い.さらに、データの一貫性についても、ロックを長時間保持したり、テーブル・レベルのロックを使用したりする必要があり、より深刻な同期性が低下するという問題があります.
これらの問題を解決するために、Oracleは第3版からマルチバージョン同時制御(Multiversion Concurrency Control,MVCC)メカニズムを使用します.これはスナップショット・アイソレーション・レベルとも呼ばれ、同期性と一貫性を同時に向上させる努力の一部です.
  • データが変更されるたびに、Undo領域に保存されます.
  • データの読み込み時に、クエリ(またはトランザクション)の開始点以降に変更された値が検出された場合、Undo領域に格納された情報を使用して、クエリ(またはトランザクション)の開始点の一貫したバージョンを生成して読み込みます.
  • クエリ中に排他的ロックのあるレコードに遭遇しても待機しないことは、ユーザに提供されるデータの基準点がクエリ(またはトランザクション)の開始点に固定されているため、一貫性を維持するのに有利である.しかし、UndoブロックI/O、CR Copy、CRブロックキャッシュの作成などの追加操作によるオーバーヘッドも無視できない.

    MVCCによる読み出し整合性


    記事レベルの読解一貫性


    データが他のトランザクションによって追加、変更または削除された場合でも、単一のSQL文内で値を一貫して読み込むことを意味します.
    コンシステンシポイント=クエリー開始時間

    システム変更番号(SCN):ブロックの最終変更時の情報
    SELECT節のSCNは10023です.すなわち、現在のブロック内のSCNが10023未満である場合、変更されたデータよりも以前のデータとみなされる.
    データブロックを読み続け、変更されたブロックが見つかった場合は、そのブロックからCRブロックを作成し、Undoレコードを読み込み、前のステップの状態にロールバックしてから読み込みます.
    (上図のように10024(現在)->10008(CR)、10024(現在)->10021(CR)にロールバックして読めばよい.)

    トランザクションレベルの読み込み一貫性


    データが他のトランザクションによって追加、変更、または削除された場合でも、トランザクション内で値を一貫して読み出すことを意味します.
    コンシステンシポイント=トランザクション開始時間
    もちろん、トランザクションの過程で、本人が行った変更は直接読まれます.

    Snapshot too old


    Undo領域に格納されたUndo情報が別のトランザクションによって再利用され、必要なCR Copyが生成されない場合に発生します.
    Snapshow tooldエラーの発生の可能性を減らすには
    1.Undo領域のサイズを大きくします.
    2.不必要な提出は頻繁に行わない.
    3.fetch over commit形式のプログラムを書くことを避け、他の方法で実現する.ANSI規格では、コミット前に開いたカーソルはFetchできません.
    4.トランザクション・セットの期間内において、長時間のクエリーが一緒に実行されないように、クエリーをグループ化して読み取り、階層化して符号化する.
    5.プログラムが同じブロックのネストされたループ形式の結合文に長時間複数回アクセスしたり、インデックスを介したテーブルにアクセスしたりして、それを回避する方法(結合方法の変更、全テーブルスキャンなど)を探しているかどうかを確認します.
    6.ウィジェット負荷を受けても、order byなどを強制的に挿入してウィジェット演算を生成します.
    7.バッチ更新直後にクエリーを実行して、テーブルまたはインデックスのスキャンを完了することも解決策です.