Oracle Database 概要 11gリリース1(11.1) E05765-03 |
|
この章では、マルチユーザー・データベース環境でのOracle Databaseによるデータ整合性の維持について説明します。
この章の内容は、次のとおりです。
シングル・ユーザーのデータベースでは、他のユーザーが同時に同じデータを変更するということがないため、ユーザーは何も心配せずにデータベース内のデータを変更できます。ただし、マルチユーザー・データベースでは、複数のトランザクション内の文によって、同じデータが同時に更新される可能性があります。同時に実行される複数のトランザクションでは、意味のある一貫した結果を出すことが必要です。したがって、マルチユーザー・データベースではデータの同時実行性と整合性の制御が重要になります。
複数のトランザクションが同時に実行される場合のトランザクションの首尾一貫した動作を記述するために、データベース研究者はシリアライズ可能性と呼ばれるトランザクションの分離モデルを定義してきました。トランザクション動作のシリアライズ可能なモードでは、複数のトランザクションは、同時にではなく1つずつ(シリアルに)実行されるように見えます。
一般に、この程度までのトランザクションの分離が望ましいとされますが、このモードで多数のアプリケーションを実行すると、アプリケーションのスループットがかなり低下する可能性があります。同時に実行される各トランザクションの完全な分離とは、あるトランザクションが問合せを実行している表に対して、他のトランザクションが挿入を実行できない状態を指します。つまり、現実には、トランザクションの完全な分離とパフォーマンスとの間の妥協点を考慮する必要があります。
Oracle Databaseの2つの分離レベルは、整合性を維持し、高いパフォーマンスを実現する操作モードをアプリケーション開発者に提供します。
この項の内容は、次のとおりです。
ANSI/ISO SQL規格(SQL-92)ではトランザクションの4つの分離レベルが定義されており、それぞれトランザクション処理のスループットに与える影響の度合いが異なります。これらの分離レベルは、複数のトランザクションを同時に実行する場合に防ぐ必要がある3つの現象という観点から定義されています。
3つの回避可能な現象とは、次のものです。
SQL-92では、それぞれの分離レベルで実行されるトランザクションで起こり得る現象という観点で4つの分離レベルを定義しています。表13-1に、各分離レベルを示します。
分離レベル | 内容を保証しない読取り | 非リピータブル・リード | 仮読取り |
---|---|---|---|
非コミット読取り |
あり |
あり |
あり |
コミット読取り |
なし |
あり |
あり |
リピータブル・リード |
なし |
なし |
あり |
シリアライズ可能 |
なし |
なし |
なし |
Oracle Databaseで使用できる分離レベルは、SQL-92の一部ではない読取り専用モードと、コミット読取りおよびシリアライズ可能です。デフォルトはコミット読取りです。
一般に、マルチユーザー・データベースでは、なんらかのデータ・ロックを使用してデータの同時実行性、一貫性、および整合性の問題を解決しています。ロックは、同じリソースにアクセスしている複数のトランザクション間で破壊的な相互作用が起きないようにするメカニズムです。
リソースには、次の2つの一般的なタイプのオブジェクトが含まれます。
Oracle Databaseは、マルチバージョン一貫性モデルや、様々なタイプのロックおよびトランザクションを使用することによって、マルチユーザー環境でのデータ整合性を維持します。この項の内容は、次のとおりです。
Oracle Databaseでは、ある問合せで参照されるデータのすべてが同一時点でのデータになるように、問合せに対して自動的に読取り一貫性が提供されます(文レベルの読取り一貫性)。Oracle Databaseの読取り一貫性は、1つのトランザクション内のすべての問合せに対しても提供できます(トランザクション・レベルの読取り一貫性)。
Oracle Databaseは、これらの一貫したデータの参照を実現するために、ロールバック・セグメント内に保持される情報を使用します。ロールバック・セグメントには、コミットされていないトランザクションまたは最近コミットされたトランザクションによって変更されたデータの元の値が含まれます。Oracle Databaseでは、図13-1に示すように、ロールバック・セグメントのデータを使用して文レベルの読取り一貫性を提供します。
問合せが実行段階に入ると、現行のシステム変更番号(SCN)が決定されます。図13-1では、このシステム変更番号が10023になっています。問合せのためにデータ・ブロックを読み取ると、監視されたシステム変更番号(SCN)が書き込まれたブロックが使用されます。変更されたデータを含むブロック(もっと後のSCN)があると、それらはロールバック・セグメント内のデータに基づいて再構成され、問合せには再構成されたデータが戻されます。そのため、問合せを実行するたびに、問合せの実行開始時点で記録されたSCNに関してコミット済のすべてのデータが戻されます。問合せの実行中に発生する他のトランザクションの変更は参照されません。このようにして、各問合せに対して一貫性のあるデータが戻されることが保証されます。
Oracle Databaseでは、常に文レベルの読取り一貫性が保たれています。これによって、1つの問合せによって戻されるすべてのデータは、その問合せが開始された時点のものであることが保証されます。そのため、問合せは、内容が保証されないデータも、その問合せの実行中にコミットされたトランザクションによって変更されたデータもまったく参照しません。問合せの実行中にその問合せで参照できるのは、その問合せが開始される前にコミットされたデータのみです。問合せは、文の実行の開始後にコミットされた変更は参照しません。
あらゆる問合せに対して一貫した結果セットが保証され、これによって、データ整合性が保証されます。この際、ユーザーは何もする必要がありません。SQL文のSELECT
、副問合せを伴うINSERT
、UPDATE
およびDELETE
は、いずれも明示的または暗黙的にデータの問合せを実行し、一貫性のあるデータを戻します。これらの文は、問合せを使用して、処理(SELECT
、INSERT
、UPDATE
またはDELETE
)の対象となるデータを決定します。
SELECT
文は明示的な問合せであり、ネストした問合せや結合操作を持つこともあります。INSERT
文では、ネストした問合せを使用できます。UPDATE
文とDELETE
文では、WHERE
句や副問合せを使用し、表のすべての行ではなく、一部の行を処理の対象にすることができます。
INSERT
文、UPDATE
文およびDELETE
文で使用される問合せでは、一貫した結果セットの取得が保証されます。ただし、そのDML文そのものによって加えられる変更は見えません。つまり、そのような操作での問合せは、その操作によって変更される前のデータの状態を参照します。
Oracle Databaseでは、トランザクション・レベルの読取り一貫性を保つこともできます。シリアライズ可能なモードでトランザクションが実行されている場合は、そのトランザクションが開始された時点でのデータベースの状態が、そのすべてのデータ・アクセスに反映されます。したがって、シリアライズ可能トランザクションが発行した問合せではそのトランザクション自身が実行した変更が参照されるという点を除けば、同一のトランザクション内にあるどの問合せで参照されるデータも、1つの時点を基準とした一貫性が保たれます。トランザクション・レベルの読取り一貫性によってリピータブル・リードが実現され、問合せで実体のないデータが検索されることもありません。
Oracle Real Application Clusters(Oracle RAC)では、読取り一貫性のあるブロックのイメージをインスタンス間で転送する際に、キャッシュ・フュージョンというキャッシュ間のブロック転送メカニズムを使用します。Oracle RACではデータ・ブロックに対するリモート要求に対応するため、待機時間の短い高速相互接続を使用してこれを行います。
Oracle Databaseは、表13-2に示すトランザクション分離レベルを提供します。
この項の内容は、次のとおりです。
アプリケーション設計者、アプリケーション開発者およびデータベース管理者は、アプリケーションとワークロードに応じて、それぞれのトランザクションに適した分離レベルを選択できます。トランザクションの分離レベルは、トランザクションの開始時に次の文のいずれかを使用して設定できます。
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET TRANSACTION READ ONLY;
各トランザクションをSET
TRANSACTION
文で開始する場合のネットワーキングおよび処理のコストを節約するために、ALTER
SESSION
文を使用して、後続のすべてのトランザクションのトランザクション分離レベルを設定することもできます。
ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE; ALTER SESSION SET ISOLATION_LEVEL = READ COMMITTED;
Oracle Databaseのデフォルト分離レベルは、コミット読取りです。このレベルの分離は、競合するトランザクションの数が少ない環境に適しています。Oracle Databaseでは、問合せごとに、それぞれ独自のマテリアライズド・ビュー時間を基準として実行されます。このため、ある問合せを複数回実行する間に非リピータブル・リードと仮読取りが発生することもありますが、高いスループットが得られます。コミット読取り分離は、競合するトランザクションの数が少ない環境に適した分離レベルです。
シリアライズ可能な分離は、次のような環境に適しています。
シリアライズ可能な分離では、同時実行トランザクションが実行できる変更は、トランザクションが順に1つずつ実行される場合に実行できるデータベース変更のみです。具体的には、Oracle Databaseでは、シリアライズ可能トランザクションでデータ行を変更できるのは、その行に対するそれ以前の変更が、シリアライズ可能トランザクションの開始時にすでにコミットされていたトランザクションによるものであると決定できる場合のみです。
この決定の効率をよくするために、Oracle Databaseでは、データ・ブロック内に格納されている制御情報、つまりブロック内の行のうち、どの行にコミットされた変更が含まれていて、どの行にコミットされていない変更が含まれているかを示す情報が使用されます。ある意味で、ブロックには、ブロック内の各行に影響を与えたトランザクションの最新の履歴が含まれていると考えられます。ここに保存される履歴の量は、CREATE
TABLE
およびALTER
TABLE
のINITRANS
パラメータによって制御されます。
Oracle Databaseでは、場合によっては、ごく最近のトランザクションで行が更新されたかどうかを決定するには履歴情報が不十分である場合もあります。これは、多数のトランザクションが同時に同じデータ・ブロックを変更している場合や、非常に短い期間にそのような操作が実行されている場合に起きることがあります。多数のトランザクションが同一のブロックを更新するような表については、INITRANS
の値を大きく設定しておくことにより、この状況を回避できます。この設定により、Oracle Databaseでは、ブロックにアクセスした最新のトランザクションの履歴を記録するために十分な記憶域が各ブロックに割り当てられます。
シリアライズ可能トランザクションが、その開始後にコミットされたトランザクションによって変更されたデータを更新または削除しようとすると、Oracle Databaseでは次のようなエラーが生成されます。
ORA-08177: Cannot serialize access for this transaction
シリアライズ可能トランザクションが失敗し、「アクセスをシリアル化できません。」というエラーが出た場合、アプリケーションは次のいずれかのアクションを実行できます。
図13-2に、「アクセスをシリアル化できません。」というエラーになったトランザクションをロールバックして再試行するアプリケーションの例を示します。
Oracle Databaseでは、アプリケーション開発者は異なる特性を持つ2つのトランザクション分離レベルのどちらかを選択できます。コミット読取りとシリアライズ可能のどちらの分離レベルでも、高度な一貫性と同時実行性が提供されます。どちらの分離レベルでも、Oracle Databaseの読取り一貫性によるマルチバージョン同時実行性制御モデルと、排他的な行レベルのロッキングが実装されることによって競合が削減されます。これらの分離レベルは、実際のアプリケーションのデプロイメントを考慮して設計されています。
この項の内容は、次のとおりです。
Oracle Databaseにおけるコミット読取りとシリアライズ可能な分離レベルを理解するため、次のような使用例を考えます。データベースの表の集合(またはデータの任意の集合)があり、それらの表内の行を特定の順序で何度か読み取り、一連のトランザクションをある特定の時点でコミットするとします。ある操作(問合せまたはトランザクション)のどの読取りでも、コミット済のトランザクションの同一の集合によって書き込まれたデータが戻される場合、その操作にはトランザクション集合の一貫性があります。一部の読取りにはあるトランザクション集合による変更が反映されており、他の読取りには別のトランザクション集合による変更が反映されている場合、その操作にはトランザクション集合の一貫性がありません。トランザクション集合の一貫性のない操作では、事実上、コミット済の1つのトランザクション集合が反映された状態のデータベースを一貫して参照できません。
Oracle Databaseでは、コミット読取りモードで実行されるトランザクションには文単位でのトランザクション集合の一貫性が提供されます。シリアライズ可能なモードでは、トランザクション単位でのトランザクション集合の一貫性が提供されます。
表13-3に、Oracle Databaseでのコミット読取りトランザクションとシリアライズ可能トランザクションの主な違いをまとめます。
コミット読取りトランザクションとシリアライズ可能トランザクションは、どちらも行レベルのロックを使用します。また、コミットされていない同時トランザクションによって更新された行を変更しようとすると、待ち状態になります。ある行を2番目に更新しようとしたトランザクションは、最初のトランザクションがコミットまたは取り消されてロックが解除されるまで、待ち状態になります。この最初のトランザクションがロールバックした場合、どの分離モードでも、待ち状態のトランザクションは最初のトランザクションが存在しなかったかのように、以前にロックされた行を変更できるようになります。
ただし、阻止している最初のトランザクションがコミットされてロックが解除された場合、コミット読取りトランザクションは、目的の更新処理を続行します。また、シリアライズ可能トランザクションの場合には、そのシリアライズ可能トランザクションの開始後になされた変更を他のトランザクションがコミットしているため、「アクセスをシリアル化できません。」エラーを出して失敗します。
Oracle Databaseは、読取り一貫性トランザクションでもシリアライズ可能トランザクションでも読取りロックを使用しないため、あるトランザクションで読み取ったデータが別のトランザクションによって上書きされる可能性があります。アプリケーション・レベルでデータベースの一貫性のチェックを実行するトランザクションでは、データの変更がトランザクションから見えなくても、読み取ったデータがトランザクションの実行中に変更されることはないとは想定しないでください。このことを考慮してアプリケーション・レベルの一貫性チェックをコーディングしないかぎり、シリアライズ可能トランザクションを使用しても、データベースの一貫性が損われることがあります。
分散データベース環境では、一部のノードのみがコミットされることがないように、複数の物理データベースが2フェーズ・コミットによって保護され、1つのトランザクションによって複数の物理データベースのデータが更新されます。そのような環境では、Oracleかどうかを問わず、シリアライズ可能トランザクションに関与するすべてのサーバーで、シリアライズ可能な分離モードがサポートされている必要があります。
シリアライズ可能トランザクションをサポートしていないサーバーによって管理されているデータベース内のデータをシリアライズ可能トランザクションが更新しようとすると、そのトランザクションにはエラーが戻されます。トランザクションを取り消して再試行できるのは、リモート・サーバーがシリアライズ可能トランザクションをサポートしている場合のみです。
これとは対照的に、コミット読取りトランザクションでは、シリアライズ可能トランザクションをサポートしていないサーバーで分散トランザクションを実行できます。
アプリケーション設計者およびアプリケーション開発者は、アプリケーションのコーディング以外にアプリケーションのパフォーマンスと一貫性のニーズに基づいて分離レベルを選択する必要があります。
多数の同時実行ユーザーが次々にトランザクションを送る環境では、トランザクションの予想到着率および応答時間の要求の面から、トランザクションのパフォーマンス要件を評価する必要があります。高いパフォーマンスが必要な環境では、分離レベルを選択する際に一貫性と同時実行性とのバランスを考慮する必要がよくあります。
データベースの一貫性のチェックを実行するアプリケーションのロジックでは、どちらのモードでも読取りによっては書込みがブロックされないという点を考慮する必要があります。
Oracle Databaseの2つの分離モードは、行レベル・ロックとOracle Databaseのマルチバージョン同時実行性制御システムとの組合せによって、高水準の一貫性、同時実行性およびパフォーマンスを提供します。Oracle Databaseでは、読取り側と書込み側が互いに処理をブロックしません。そのため、問合せで一貫性のあるデータが参照される一方で、コミット読取りとシリアライズ可能などちらの分離レベルでも、コミットされていないデータを読むことなく、高パフォーマンスを実現する高水準の同時実行性を提供します。
この項の内容は、次のとおりです。
多くのアプリケーションでは、コミット読取りが最適な分離レベルです。コミット読取り分離では、同時実行性が大幅に向上する一方で、一部のトランザクションでは、仮読取りや非リピータブル・リードのために、一貫性のない結果が生じる危険性が多少高くなります。
トランザクションの到着率が高く、高いパフォーマンスが求められる多くの環境では、シリアライズ可能な分離レベルによって実現されるよりも大きなスループットと高速な応答時間が必要になる場合があります。サポートするユーザーが少数で、トランザクション到着率が非常に低い環境では、仮読取りおよび非リピータブル・リードによって間違った結果が生じる危険性が非常に低くなります。コミット読取り分離は、いずれの環境にも適しています。
Oracle Databaseのコミット読取り分離では、すべての問合せについてトランザクション集合の一貫性が提供されます。つまり、どの問合せでも一貫性のある状態のデータが参照されます。したがって、マルチバージョン同時実行性制御を使用しない他のデータベース管理システム上で実行される場合にはさらに高水準の分離を必要とするようなアプリケーションでも、多くの場合、コミット読取り分離で十分に対応できます。
コミット読取り分離モードでは、アプリケーションのロジックで「アクセスをシリアル化できません。」というエラーをトラップしたり、処理をロールバックしてトランザクションを再起動する必要はありません。大部分のアプリケーションでは、同じ問合せを2回繰り返して発行するという機能的必要があるトランザクションはごく少数のため、仮読取りおよび非リピータブル・リードの防止は重要ではありません。したがって、前述のようなエラー・チェックや再試行のコードを各トランザクションで記述する必要を避けるために、多くの開発者はコミット読取りを選択します。
Oracle Databaseのシリアライズ可能な分離は、2つの同時トランザクションが同じ行を更新する機会が比較的少なく、長時間にわたって実行されるトランザクションが主に読取り専用である環境に適しています。この分離モードが最も適しているのは、大規模なデータベースを使用し、短いトランザクションでごく少数の行のみが更新される環境です。
シリアライズ可能な分離モードは、仮読取りと非リピータブル・リードを防止することである程度まで一貫性を向上できるため、読取り/書込みトランザクションが1つの問合せを複数回実行する場合に重要になることがあります。
他の処理系のシリアライズ可能な分離では書込みのみでなく読取りについてもブロックがロックされるのに対し、Oracle Databaseでは非ブロック化問合せときめ細かい行レベル・ロックが提供され、それらによって読取り/書込みの競合が少なくなります。読取り/書込みの競合が多く発生するアプリケーションでは、Oracle Databaseのシリアライズ可能な分離は、他のシステムより大幅に高いスループットを提供します。このため、Oracle Database上ではシリアライズ可能な分離に適していても、他のシステムではシリアライズ可能な分離に適さないアプリケーションもあります。
Oracle Databaseのシリアライズ可能トランザクション内のすべての問合せは、一時点でのデータベースを参照するため、読取り/書込みトランザクションで複数の一貫した問合せを発行する必要がある場合は、この分離レベルが適しています。シリアライズ可能なモードでは、READ ONLY
トランザクションで実現される一貫性が確保される一方で、INSERT
、UPDATE
およびDELETE
トランザクションも実行できるため、サマリー・データを生成してそのデータをデータベースに格納する報告書作成アプリケーションでは、シリアライズ可能なモードを使用できます。
アプリケーション開発者がシリアライズ可能トランザクションをコーディングする場合には、「アクセスをシリアル化できません。」のエラーのチェックとトランザクションの取消しおよび再試行のために、追加の作業が必要になります。他のデータベース管理システムでデッドロックを管理する際にも、同様の追加コーディングが必要です。社内標準を遵守する場合や、複数のデータベース管理システム上で実行するアプリケーションを作成する場合には、シリアライズ可能なモードに対応したトランザクションの設計が必要なことがあります。シリアライズの可能性エラーをチェックして、再試行するトランザクションは、Oracle Databaseのコミット読取りモード、つまりシリアライズの可能性エラーを生成しないモードで使用できます。
シリアライズ可能なモードにあまり適さないのは、大量の短い更新トランザクションでアクセスするのと同じ行を、比較的長いトランザクションで更新する環境です。このような環境では、長時間実行のトランザクションが行を最初に変更するという可能性は低いため、頻繁なロールバックが必要となり、作業が無駄になります。従来型の読取りをロックしたシリアライズ可能なモードの即時実行であり、この環境には適していません。長時間実行されるトランザクションは、読取りトランザクションであっても、短い更新トランザクションの処理を阻止したり、逆に短いトランザクションが長時間実行のトランザクションの処理を阻止する場合があるためです。
アプリケーション開発者は、シリアライズ可能なモードを使用するときはトランザクションのロールバックと再試行に要するコストを考慮する必要があります。デッドロックが頻繁に発生する読取りロックのシステムと同様に、シリアライズ可能なモードを使用するときには、終了したトランザクションによって実行された処理をロールバックし、再実行する必要が生じます。競合が頻繁に発生する環境では、このアクティビティでリソースが著しく使用されます。
ほとんどの環境では、「アクセスをシリアル化できません。」のエラーを受け取った後で再起動されたトランザクションと別のトランザクションの間で、二度目の競合が発生することはめったにありません。このため、他のトランザクションと競合する可能性の高い文は、シリアライズ可能トランザクション内の可能なかぎり前の部分で実行するとよい場合があります。ただし、そのトランザクションが正常に完了する保証はないため、再試行の回数を制限するようにアプリケーションをコーディングしておく必要があります。
Oracle Databaseのシリアライズ可能なモードにはSQL-92との互換性があり、読取りロックの処理系と比較して多くの利点がありますが、意味としてはそれらのシステムと同じではありません。アプリケーション設計者は、Oracle Databaseでの読取りは、他のシステムとは異なり、書込みをブロックしないという点を考慮する必要があります。データベースの一貫性をアプリケーション・レベルでチェックするトランザクションでは、SELECT FOR UPDATE
などのコーディング技法を使用することが必要な場合があります。シリアライズ可能なモードを使用しているアプリケーションを他の環境からOracle Databaseに移植する場合には、この問題を検討する必要があります。
システムを静止状態にできます。SYS
とSYSTEM
以外のアクティブなセッションがない場合は、システムは静止状態になっています。アクティブなセッションは、現行のトランザクション、問合せ、フェッチ、PL/SQLプロシージャの中にあるセッション、または現在いずれかの共有リソース(エンキューなど)を保持しているセッションとして定義されています(エンキューは、データベース・リソースへのアクセスをシリアライズする共有メモリー構造で、セッションまたはトランザクションに関連付けられています)。データベース管理者は、システムが静止状態にある際に進行処理のできる唯一のユーザーです。
データベース管理者は、システムが静止状態でなければ安全に行えない特定のアクションを実行できます。このアクションには次のようなものがあります。
T
と、それを操作するPL/SQLパッケージがあるとします。表T
を2つの表T1
およびT2
に分割し、PL/SQLパッケージを変更して、元の表T
のかわりに新規の表T1
およびT2
を参照させることができます。 データベースが静止状態になると、次を実行できます。
CREATE TABLE T1 AS SELECT ... FROM T; CREATE TABLE T2 AS SELECT ... FROM T; DROP TABLE T;
これで元のPL/SQLパッケージを削除して再作成できます。
継続的に操作する必要のあるシステムでは、このようなアクションをデータベースを停止せずに実行する機能は重要です。
データベース・リソース・マネージャは、システムの静止中にSYS
またはSYSTEM
以外のユーザーが開始したアクションをすべてブロックします。これらのアクションは、システムが通常の(静止中でない)状態に戻ると実行されます。ユーザーに対して、静止状態によるそれ以外のエラー・メッセージはありません。
データベース管理者は、ALTER
SYSTEM
QUIESCE
RESTRICTED
文を使用してデータベースを静止させます。ユーザーSYS
およびSYSTEM
のみが、ALTER
SYSTEM
QUIESCE
RESTRICTED
文を発行できます。この文を発行すると、オープンしているデータベースのすべてのインスタンスに対して、次のような影響があります。
SYS
とSYSTEM
以外)がアクティブにならないように指示します。SYS
とSYSTEM
以外のユーザーは、新しいトランザクション、問合せ、フェッチまたはPL/SQL操作を開始できません。
SYS
とSYSTEM
以外のユーザーが開始した、すべてのインスタンスの既存トランザクションがすべて終了(コミットまたは終了)するまで待機します。また、Oracle Databaseでは、SYS
とSYSTEM
以外のユーザーが開始した、トランザクション外部にあるすべてのインスタンスの実行中の問合せ、フェッチおよびPL/SQLプロシージャがすべて終了するまで待機します。ただし、問合せが連続する複数のOCIフェッチによって実行されている場合、Oracle Databaseはそのすべての終了までは待機しません。現在実行中のフェッチのみを終了させ、次のフェッチはブロックします。また、Oracle Databaseでは共有リソース(エンキューなど)を保持するすべてのセッション(SYS
とSYSTEM
のセッション以外)が、そのリソースを解放するまで待機します。これらの操作がすべて終了した後、Oracle Databaseはデータベースを静止状態にして、QUIESCE RESTRICTED
文の実行を完了します。
SYS
とSYSTEM
以外)をブロックするよう指示します。インスタンスが共有サーバー・モード以外で実行中の場合は、Oracle Databaseではそのインスタンスに対するユーザーのログインは制限されません。
静止状態の間は、インスタンスのリソース・マネージャ・プランは変更できません。
ALTER
SYSTEM
UNQUIESCE
文を発行すると、実行中のすべてのインスタンスが通常モードに戻り、ブロックされたアクションがすべて実行可能になります。管理者は、v$blocking_quiesce
ビューを問い合せて、静止の完了をブロックしているセッションを判断できます。
ロックは、同じリソース、つまりユーザー・オブジェクト(表や行など)またはユーザーには見えないシステム・オブジェクト(メモリー内の共有データ構造やデータ・ディクショナリ行など)のどちらかにアクセスする複数のトランザクション間で、破損を招く相互作用を回避するためのメカニズムです。
どのような状況でも、SQL文が実行されると、Oracle Databaseによって必要なロックが自動的に取得されます。そのため、ユーザーがそのような詳細事項にかかわる必要はありません。Oracle Databaseは、最も高度なデータ同時実行性とフェイルセーフなデータ整合性を同時に実現するために、最も低いレベルの制限でデータを自動的にロックします。Oracle Databaseではまた、必要に応じて、手動でもデータをロックできます。
この項の内容は、次のとおりです。
Oracle Databaseではロック・メカニズムを使用して、トランザクション間のデータの同時実行性と整合性を実現します。Oracle Databaseのロック・メカニズムはトランザクション制御と密接に結び付けられているため、アプリケーション設計者がトランザクションを適切に定義するだけで、ロックはOracle Databaseによって自動的に管理されます。
Oracle Databaseのロックは完全に自動化されていて、ユーザー・アクションを必要としません。すべてのSQL文について暗黙的ロックが発生するため、データベース・ユーザーがリソースを明示的にロックする必要はありません。Oracle Databaseのデフォルトのロック・メカニズムは、最高水準のデータ同時実行性を実現しながら、データ整合性を保証するために、最も低い制限レベルでデータをロックします。
この項の内容は、次のとおりです。
Oracle Databaseでは、マルチユーザー・データベースで2つのロック・モードを使用します。
あるトランザクション内の文によって取得されたすべてのロックは、そのトランザクションの継続時間中は保持され、同時実行のトランザクションによる有害な干渉(内容を保証しない読取り、更新内容の消失、有害なDDL操作など)が防止されます。あるトランザクションのSQL文によって加えられた変更を参照できるのは、そのトランザクションがコミットされた後に開始される別のトランザクションのみです。
トランザクションをコミットまたは取り消すと、Oracle Databaseでは、そのトランザクション内の文によって取得されたすべてのロックが解除されます。また、Oracle Databaseでは、セーブポイントまでロールバックすると、そのセーブポイントより後で取得されたロックが解除されます。ただし、ロックを解除されて使用可能となったリソースに対してロックを取得できるのは、ロック中だったリソースを待機していなかったトランザクションのみです。ロック中のリソースを待機していたトランザクションは、元のトランザクションが完全にコミットされるかロールバックされるまで待機し続けます。
トランザクションは、トランザクション内で挿入、更新または削除の対象になる行すべてに対して排他ロックを保持します。行ロックは、制限の最も高い程度で取得されるため、ロック変換はまったく必要なく、実行されません。
Oracle Databaseは、低い制限の表ロックを、より高い制限の適切な表ロックに自動的に変換します。たとえば、トランザクションが表の行をロックするために、FOR
UPDATE
句を指定したSELECT
文を使用する場合を考えます。その結果、排他行ロックとその表に対する行共有表ロックが取得されます。後で、トランザクションがロック中の1つ以上の行を更新する場合、行共有表ロックは自動的に行排他表ロックに変換されます。
ロックの段階的拡大が発生するのは、あるレベル(行レベルなど)で多数のロックが保持されている場合に、各ロックをデータベースが上位レベル(表レベルなど)の別のロックに変更した場合です。たとえば、あるユーザーが表の中の多数の行をロックした場合、データベースによっては、そのユーザーが保持する複数の行ロックを単一の表ロックに自動的に拡大する場合があります。ロックの数は少なくなりますが、ロックされている対象の制限は大きくなります。
Oracle Databaseでは、ロックの段階的拡大が発生することはありません。ロックの段階的拡大はデッドロックの可能性を大幅に増します。たとえば、システムがトランザクションT1のためにロックを拡大しようとしますが、トランザクションT2によって保持されているロックのために拡大できないものとします。トランザクションT2の処理を進めるのに同じデータのロックの段階的拡大が必要な場合、デッドロックが発生します。
デッドロックが発生するのは、2人以上のユーザーが、相手がロックしているデータを待機している場合です。デッドロックが発生すると、一部のトランザクションは処理を継続できなくなります。図13-3に、デッドロック状態になっている2つのトランザクション例を示します。
図13-3において、各トランザクションはそれ自体が更新しようとする行に対して行ロックを保持するため、Aの時点では問題は存在しません。各トランザクションの処理は、終了せずに進行します。ただし、各トランザクションは、次に、他方のトランザクションが現在保持している行を更新しようとします。したがって、どちらのトランザクションも処理の進行や終了に必要となるリソースを取得できないため、結局、Bの時点でデッドロックが発生します。デッドロックになるのは、それぞれのトランザクションがいくら待機しても、競合するロックが保持されるためです。
この項の内容は、次のとおりです。
Oracle Databaseは、デッドロック状況を自動的に検出し、そのデッドロックに含まれる文の1つをロールバックして、競合する一連の行ロックを解放することにより、デッドロックを解決します。また、対応するメッセージが、文レベルのロールバックの対象となったトランザクションに戻されます。ロールバックされる文は、デッドロックが検出されたトランザクションに属しています。通常、通知されたトランザクションは明示的にロールバックする必要がありますが、待機した後でロールバック文を再試行できます。
デッドロックが最も頻繁に発生するのは、トランザクションがOracle Databaseのデフォルト・ロックを明示的にオーバーライドする場合です。Oracle Database自体はロックの段階的拡大を実行せず、また、問合せに読取りロックを使用しませんが行レベルのロック(ページ・レベルのロックではありません)は使用するため、Oracle Databaseでデッドロックはまれにしか起こりません。
多くの場合、複数表のデッドロックは、複数の同じ表にアクセスする複数のトランザクションが、暗黙的ロックまたは明示的ロックを通じて各表を同じ順序でロックすれば回避できます。たとえば、すべてのアプリケーション開発者は、マスター表とディテール表の両方を更新するときに、まずマスター表をロックしてからディテール表をロックするという規則に従ってください。この規則を適切に設計し、すべてのアプリケーションがそれに従えば、デッドロックが起こる可能性はかなり低くなります。
あるトランザクションについて一連のロックが必要となることがわかっているときは、最も排他的な(最も共存不能な)ロックが最初に取得されるように考慮してください。
Oracle Databaseは、データへの同時アクセスを制御し、各ユーザー間の有害な干渉を防止するために、様々な種類のロックを自動的に使用します。Oracle Databaseは、トランザクションのためにリソースを自動的にロックし、他のトランザクションが同じリソースの排他的アクセスを要求する処理を行うことを防止します。なんらかのイベントが発生し、トランザクションがそのリソースを必要としなくなると、ロックは自動的に解除されます。
全操作を通じて、Oracle Databaseは、ロックされるリソースと実行される操作に応じて、様々な制限レベルの様々な種類のロックを自動的に取得します。
Oracle Databaseのロックは、表13-4に示された3つの一般的なカテゴリのいずれかに分類されます。
次の各項では、DMLロック、DDLロックおよび内部ロックについて説明します。
DMLロック(データ・ロック)の目的は、複数のユーザーが同時にアクセスするデータの整合性を保証することです。DMLロックは、同時に実行される矛盾する複数のDML操作またはDDL操作の破損を招く干渉を防ぎます。DML文では、表レベル・ロックおよび行レベル・ロックの両方が自動的に取得されます。
この項の内容は、次のとおりです。
行レベル・ロックは、主に、2つのトランザクションによる同じ行の変更を防ぐ目的で使用されます。トランザクションで行を変更する必要がある場合、行ロックが取得されます。
1つの文またはトランザクションで保持できる行ロックの数に制限はありません。また、Oracle Databaseが行レベルのロックからロックの単位を拡大することはありません。行ロックでは、最もきめの細かいロックが実現されるため、最高の同時実行性とスループットが得られます。
マルチバージョン同時実行性制御と行レベル・ロックを組み合せると、同じデータに関して複数のユーザーが競合するのは、同じ行にアクセスする場合のみになります。特に、次のような場合です。
SELECT
... FOR
UPDATE
を使用している場合は除きます。
INSERT
文、UPDATE
文、DELETE
文、およびFOR
UPDATE
句を含むSELECT
文のいずれかで変更された行ごとに、トランザクションは排他行ロックを取得します。
変更された行は、ロックを保持しているトランザクションがコミットされるかロールバックされるまで、他のトランザクションがその行を変更できないように常に排他的にロックされます。ただし、インスタンス障害のためにトランザクションが終了すると、トランザクション全体がリカバリされる前に、ブロック・レベルのリカバリによって行が使用可能になります。行ロックは、前にリストされた文の結果として、Oracle Databaseによって常に自動的に取得されます。
ある行について行ロックを取得したトランザクションは、その行に対応する表についての表ロックも取得します。表ロックがあると、カレント・トランザクション内のデータ変更をオーバーライドするDDL操作の競合が回避されます。
表レベル・ロックは、DML操作中に表が削除されないようにするなど、主に同時実行DDL操作で同時実行性制御を行うために使用されます。DDL文またはDML文が表に対するものである場合、表ロックが取得されます。表ロックは、DML操作の同時実行性には影響しません。パーティション表の場合、表およびサブパーティションの両方のレベルで表ロックを取得できます。
INSERT
文、UPDATE
文、DELETE
文、FOR
UPDATE
句付きのSELECT
文およびLOCK
TABLE
文の各DML文で表が変更される場合、トランザクションは表ロックを取得します。これらのDML操作が表ロックを必要とするのは、トランザクションのために表へのDMLアクセスを確保すること、およびトランザクションと競合する可能性があるDDL操作を防止するという2つの目的のためです。すべての表ロックは同じ表に対する排他DDLロックを防止するため、そのようなロックを必要とするDDL操作も防止されます。たとえば、コミットされていないトランザクションが、ある表について表ロックを保持している場合、その表を変更したり削除することはできません。
表ロックは、行共有(RS)、行排他(RX)、共有(S)、共有行排他(SRX)および排他(X)のいずれかのモードで保持できます。表ロックのモードの制限は、他の表ロックが同じ表について取得し、保持できるモードを決定します。
表13-5に、文が取得する表ロックのモードを示します。表の最後の5列は、表ロックで許可(可
)および禁止(否
)される操作を示します。
RS: 行共有
RX: 行排他
S: 共有
SRX: 共有行排他
X: 排他
* 別のトランザクションによって、競合する行ロックが保持されていない場合。そうでない場合は待機が発生。
この後、制限レベルの低いものから高いものという順序で、表ロックの各モードについて説明します。また、トランザクションがそのモードで表ロックを取得する原因となるアクションや、そのモードのロックで他のトランザクションに許可されるアクションと禁止されるアクションについても説明します。
この項の内容は、次のとおりです。
行共有表ロック(副共有表ロック、SSとも呼ぶ)は、この表ロックを保持しているトランザクションが、その表の行をロックし、それらの行を更新する予定であることを示します。次のSQL文が実行された場合は、表の行共有表ロックが自動的に取得されます。
LOCK TABLE table IN ROW SHARE MODE;
行共有表ロックは、最も制限の緩やかなモードの表ロックであり、最高度の同時実行性を表に提供します。
許可される操作: トランザクションによって保持される行共有表ロックでは、他のトランザクションは、同じ表の中の行に対して問合せ、挿入、更新、削除またはロックを同時に実行できます。そのため他のトランザクションは、同じ表について同時に行共有ロック、行排他ロック、共有ロックおよび共有行排他ロックを取得できます。
禁止される操作: トランザクションによって保持される行共有表ロックは、他のトランザクションが次の文のみを使用して同じ表に排他書込みアクセスを実行するのを防止します。
LOCK TABLE table IN EXCLUSIVE MODE;
行排他表ロック(副排他表ロック、SXとも呼ぶ)は、一般に、このロックを保持しているトランザクションが、表の中またはSELECT
... FOR
UPDATE
で発行された行に対して1つ以上の更新を行ったことを示します。行排他表ロックは、次のタイプの文によって修正される表について自動的に取得されます。
SELECT ... FROM table ... FOR UPDATE OF ... ; INSERT INTO table ... ; UPDATE table ... ; DELETE FROM table ... ; LOCK TABLE table IN ROW EXCLUSIVE MODE;
行排他表ロックでは、行共有表ロックよりも少し多くの制限が課されます。
許可される操作: トランザクションによって保持される行排他表ロックでは、他のトランザクションは、同じ表の中の行に対して問合せ、挿入、更新、削除またはロックを同時に実行できます。そのため、行排他表ロックによって、複数のトランザクションが同時に、同じ表について行排他ロックと行共有表ロックを取得できます。
禁止される操作: トランザクションによって保持される行排他表ロックは、他のトランザクションが排他的な読取りや書込みを実行するために表を手動でロックすることを防止します。そのため、他のトランザクションは、次の文を使用して同時に表をロックすることはできません。
LOCK TABLE table IN SHARE MODE; LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE; LOCK TABLE table IN EXCLUSIVE MODE;
共有表ロックは、次の文で指定される表について自動的に取得されます。
LOCK TABLE table IN SHARE MODE;
許可される操作: トランザクションによって保持される共有表ロックでは、他のトランザクションは、表の問合せ(SELECT
... FOR
UPDATE
の使用は除く)、またはLOCK
TABLE
... IN
SHARE
MODE
文の正常な実行のみが許可されます。他のトランザクションによる更新は許可されません。複数のトランザクションが、同じ表について同時に共有表ロックを保持できます。ただし、この場合、トランザクションは表を更新できません。そのため、共有表ロックを保持しているトランザクションがその表を更新できるのは、他のトランザクションが同じ表について共有表ロックを保持していない場合のみです。
禁止される操作: トランザクションによって保持される共有表ロックは、他のトランザクションが同じ表を変更するのを禁止します。また、他のトランザクションが次の文を実行することも禁止します。
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE; LOCK TABLE table IN EXCLUSIVE MODE; LOCK TABLE table IN ROW EXCLUSIVE MODE;
共有行排他表ロック(共有副排他表ロック、SSXとも呼ぶ)は、共有表ロックよりも多くの制限を課します。共有行排他表ロックは、次の文で指定された表について取得されます。
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE;
許可される操作: 一度に1つのトランザクションのみが、特定の表の共有行排他表ロックを取得できます。トランザクションによって保持される共有行排他表ロックでは、他のトランザクションは表の問合せ(SELECT
... FOR
UPDATE
の使用は除く)は許可されますが、表の更新は許可されません。
禁止される操作: トランザクションによって保持される共有行排他表ロックは、他のトランザクションによる行排他表ロックの取得、および同じ表の変更を防止します。また、共有行排他表ロックでは、他のトランザクションが共有ロック、共有行排他ロックおよび排他表ロックを取得することが禁止されます。つまり、他のトランザクションが次の文を実行できなくなります。
LOCK TABLE table IN SHARE MODE; LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE; LOCK TABLE table IN ROW EXCLUSIVE MODE; LOCK TABLE table IN EXCLUSIVE MODE;
排他表ロックは、最も多くの制限が課されるモードの表ロックであり、ロックを保持するトランザクションが表に排他的に書込みアクセスすることを許可します。排他表ロックは、次の文で指定された表について取得されます。
LOCK TABLE table IN EXCLUSIVE MODE;
許可される操作: 1つのトランザクションのみが、表の排他表ロックを取得できます。排他表ロックでは、他のトランザクションは同じ表に対する問合せのみを実行できます。
禁止される操作: トランザクションによって保持されている排他表ロックは、他のトランザクションによるDML文の実行とその表に対するロックの適用を禁止します。
これまで、各種データ・ロックのタイプと、どのモードで保持できるか、いつ取得できるか、いつ取得されるか、何を禁止するかについて説明しました。次の項では、異なるDML操作に対するOracle Databaseでのデータの自動的なロックについて説明します。
表13-6に、次の項で説明する情報の概要を示します。
X: 排他
RX: 行排他
RS: 行共有
S: 共有
SRX: 共有行排他
この項の内容は、次のとおりです。
問合せはデータを読み取るのみであるため、他のSQL文に対してほとんど干渉しないSQL文です。INSERT
文、UPDATE
文およびDELETE
文には、文の一部として暗黙的問合せが含まれている場合があります。問合せには、次の種類の文が含まれます。
SELECT INSERT ... SELECT ... ; UPDATE ... ; DELETE ... ;
次の文は含まれません。
SELECT ... FOR UPDATE OF ... ;
次の特性は、FOR
UPDATE
句を使用しないすべての問合せに当てはまります。
FOR
UPDATE
句が指定されていない問合せでは、データ・ロックが取得されないので他の操作はブロックされないため、Oracle Databaseではこの問合せを非ブロック化問合せと呼ぶことがあります。
INSERT
、UPDATE
、DELETE
およびSELECT
... FOR
UPDATE
文のロックの特徴は次のとおりです。
WHERE
句の中にある問合せ)によって選択される行に対して行ロックを取得する必要がありません。DML文の中の副問合せや暗黙的問合せは、問合せの開始時点での一貫性が保証され、元のDML文自体の影響を参照しません。
処理中のデータ・ディクショナリ・ロック(DDL)操作によってスキーマ・オブジェクトが影響を受けたり参照される間、そのオブジェクトの定義はDDLロックによって保護されます。DDL文がトランザクションを暗黙のうちにコミットすることに注意してください。たとえば、ユーザーがプロシージャを作成する場合を考えます。そのユーザーの単一文トランザクションのために、Oracle Databaseはプロシージャ定義で参照されるすべてのスキーマ・オブジェクトについてのDDLロックを自動的に取得します。そのDDLロックにより、プロシージャのコンパイル完了前に、プロシージャで参照されるオブジェクトの変更または削除が防止されます。
Oracle Databaseは、ディクショナリ・ロックを必要とするDDLトランザクションのために、ディクショナリ・ロックを自動的に取得します。ユーザーはDDLロックを明示的に要求できません。DDL操作中には、修正や参照の対象となる個々のスキーマ・オブジェクトのみがロックされます。データ・ディクショナリ全体がロックされることはありません。
DDLロックは、排他DDLロック、共有DDLロックおよびブレーク可能解析ロックの3つに分類されます。
この項の内容は、次のとおりです。
「共有DDLロック」の項に示されているDDL操作を除き、ほとんどのDDL操作では、同じスキーマ・オブジェクトの変更や参照を実行する可能性のある他のDDL操作によって破壊的な干渉が起きないように、リソースの排他DDLロックが必要です。たとえばALTER TABLE
操作で表に列を追加している間は、DROP TABLE
操作でその表を削除できません。その逆も同様です。
排他DDLロックの取得では、別の操作によってすでにそのスキーマ・オブジェクトに対して別のDDLロックが保持されている場合、その取得は古いDDLロックが解除されるまで待機し、その後に処理されます。
また、DDL操作は変更対象のスキーマ・オブジェクトに対するDMLロック(データ・ロック)も取得します。
ある種のDDL操作では、競合するDDL操作によって破壊的な干渉が起きないようにし、かつ一方では類似のDDL操作についてデータの同時実行性を確保するため、リソースの共有DDLロックが必要です。たとえばCREATE
PROCEDURE
文の実行時には、その文を含むトランザクションは、参照されるすべての表について共有DDLロックを取得します。他のトランザクションは同じ表を参照するプロシージャを同時に作成できるため、同じ表について同時実行の共有DDLロックを取得できます。ただし、参照中の表について排他DDLロックを取得できるトランザクションはありません。また、参照中の表を変更または削除できるトランザクションはありません。その結果、共有DDLロックを保持するトランザクションでは、参照中のスキーマ・オブジェクトの定義がそのトランザクションの継続時間にわたって変化しないことが保証されます。
スキーマ・オブジェクトに対する共有DDLロックは、AUDIT
、NOAUDIT
、COMMENT
、CREATE
(またはREPLACE
)VIEW
/ PROCEDURE
/PACKAGE/PACKAGE
BODY
/FUNCTION
/ TRIGGER
、CREATE SYNONYM
およびCREATE
TABLE
(CLUSTER
パラメータが含まれていない場合)などのDDL文に対して取得されます。
共有プール内のSQL文(またはPL/SQLプログラム・ユニット)は、参照される各スキーマ・オブジェクトについて解析ロックを保持します。参照オブジェクトが変更されたり削除されたりした場合に、対応する共有SQL領域を無効にできるようにするため、解析ロックが取得されます。解析ロックは、どのようなDDL操作も拒否せず、矛盾するDDL操作も許可するためにブレーク(中断)できるため、ブレーク可能解析ロックと呼ばれます。
解析ロックはSQL文の実行の解析フェーズで取得され、共有プールの中にその文の共有SQL領域が残っているかぎり保持されます。
DDLロックの継続時間は、DDLロックの種類によって異なります。排他ロックと共有DDLロックは、DDL文実行の継続中と自動コミット中ずっと存続します。解析ロックは、対応するSQL文が共有プールに残っているかぎり存続します。
クラスタに対するDDL操作は、クラスタおよびそのクラスタ内のすべての表とマテリアライズド・ビューに対して排他DDLロックを取得します。クラスタ内の表やマテリアライズド・ビューに対するDDL操作は、その表やマテリアライズド・ビューに対する共有DDLロックまたは排他DDLロックに加えて、そのクラスタに対する共有ロックも取得します。クラスタに対する共有DDLロックは、最初の操作の処理中に、別の操作がそのクラスタを削除するのを防止します。
ラッチと内部ロックは、内部データベース構造とメモリー構造を保護します。ユーザーは、それらの出現や継続時間を制御する必要がないため、そのいずれもユーザーからはアクセスできません。次の項の説明内容は、Enterprise Managerを使用したロック
とラッチ
の監視について理解する上で役立ちます。
この項の内容は、次のとおりです。
ラッチは、システム・グローバル領域(SGA)内の共有データ構造を保護するための単純な下位レベルのシリアライズ・メカニズムです。たとえば、ラッチは現在データベースにアクセスしているユーザーのリストと、バッファ・キャッシュ内のブロックを説明しているデータ構造を保護します。サーバー・プロセスまたはバックグラウンド・プロセスは、これらの構造の1つを操作したり参照する、非常に短い間のみラッチを取得します。ラッチのインプリメンテーション(特に、プロセスがラッチを待機するかどうか、およびどれくらいの時間待機するか)は、オペレーティング・システムに依存します。
内部ロックは、ラッチよりも高水準で複雑なメカニズムであり、いろいろな目的のために機能します。
この項の内容は、次のとおりです。
これらのロックの継続時間は非常に短く、ディクショナリ・キャッシュ内のエントリが修正されたり使用されている間、そのエントリについて保持されます。これらのロックは、解析されている文が矛盾したオブジェクト定義を参照しないことを保証します。
ディクショナリ・キャッシュ・ロックは、共有または排他で保持されます。共有ロックは、解析が完了すると解除されます。排他ロックは、DDL操作が完了すると解除されます。
これらのロックは様々なファイルを保護します。たとえば、あるロックは制御ファイルを保護し、一度に1つのプロセスのみがそれを変更できるようにします。別のロックは、REDOログ・ファイルの使用とアーカイブを調整します。データベースを複数インスタンスが共有モードでマウントしたり、1つのインスタンスが排他モードでマウントすることを保証するために、データファイルがロックされます。ファイルとログのロックはファイルの状態を示すため、必然的に長い間保持されます。
これらのロックは、表領域とロールバック・セグメントを保護します。たとえば、データベースにアクセスするすべてのインスタンスは、表領域のオンライン/オフラインの状態について一致している必要があります。ロールバック・セグメントは、1つのセグメントに1つのインスタンスしか書き込めないようにロックされています。
データの同時実行性、整合性および文レベルの読取り一貫性を確保するために、Oracle Databaseは常に自動的にロックを実行します。ただし、Oracle Databaseでは、デフォルトのロック・メカニズムを置き換えることもできます。デフォルト・ロックの置換えは、次のような状況で有効です。
Oracle Databaseの自動ロックは、トランザクション・レベルまたはセッション・レベルでオーバーライドできます。
トランザクション・レベルでは、次のSQL文を含むトランザクションによってOracle Databaseのデフォルト・ロックがオーバーライドされます。
TRANSACTION
ISOLATION
LEVEL
文
LOCK
TABLE
文(表をロックする文、またはビューを使用するときにその基礎となる実表をロックする文)
SELECT
... FOR
UPDATE
文
これらの文で取得されたロックは、トランザクションがコミットまたはロールバックされた後で解除されます。
セッション・レベルでは、ALTER
SESSION
文を使用して必要なトランザクション分離レベルを設定できます。
アプリケーション開発者は、Oracle Databaseのロック・マネージメント・サービスを使用して次のような処理をする文をPL/SQLブロックに含めることができます。
確保したユーザー・ロックは、Oracle Databaseロックと同一とみなされるため、デッドロックの検出などのOracle Databaseロックの機能をすべて備えています。ユーザー・ロックは接頭辞UL
で識別されるため、Oracle Databaseロックと矛盾することはありません。
Oracle Databaseのロック・マネージメント・サービスは、DBMS_LOCK
パッケージ内のプロシージャを介して利用できます。
Oracle Flashback Queryを使用すると、履歴データを表示および修復できます。特定の実時間またはユーザー指定のシステム変更番号(SCN)による、データベースへの問合せを実行できます。
フラッシュバック問合せでは、Oracle Databaseのマルチバージョン読取り一貫性機能を使用しており、必要に応じてUNDOを適用することでデータをリストアします。Oracle Database 11gでは、UNDO保存期間と呼ばれるパラメータが自動的にチューニングされます。UNDO保存期間とは、古いUNDO情報(コミットされたトランザクションのUNDO情報)が上書き可能になるまでの時間を示します。データベースにより、使用統計が収集され、これらの統計およびUNDO表領域サイズに基づいてUNDO保存期間がチューニングされます。
フラッシュバック問合せを使用すると、その日の朝、前日または前週のデータベースの状態を問い合せることができます。この操作のスピードは、問い合せるデータの量と、そのデータを元へ戻すための変更の回数にのみ依存します。
特定の行またはトランザクションの履歴を問い合せることができます。データベースに格納されているUNDOデータを使用すると、ある行の全バージョンを表示して以前のバージョンに戻すことができます。フラッシュバック・トランザクション問合せの履歴は、トランザクション・レベルでデータベースに対して行われた変更を検査する上で役立ちます。
表の各行を監査し、その行を変更したトランザクションと変更日時に関する情報を取得できます。トランザクションIDを使用すると、LogMinerを介したトランザクション・マイニングを実行して、トランザクションの詳細情報を取得できます。
表示する日付と時間を設定します。次にSQL問合せを実行すると、設定した時間におけるデータに対して問合せが行われます。権限を持つユーザーは、管理者の介入なしにエラーを訂正したりリストアされたデータをバック・アウトできます。
SQLのAS OF
句を使用すると、問合せで表ごとに異なるスナップショットを選択できます。スナップショットを表に関連付ける操作は、表の修飾と呼ばれます。表をスナップショットで修飾しない場合は、デフォルトのスナップショットが使用されます。スナップショットが指定されていない表はすべて、同じデフォルト・スナップショットを取得します。
たとえば、過去1時間以内に作成されたすべての新規顧客アカウントを検索する問合せを作成するとします。異なるAS
OF
句で修飾された同じ表の2つのインスタンスに対して、集合演算を実行できます。
DML操作とDDL操作では、表の修飾を使用して、副問合せ内でスナップショットを選択できます。INSERT TABLE AS SELECT
やCREATE TABLE AS SELECT
などの操作を副問合せで表の修飾とともに使用して、行が誤って削除された表を修復できます。表の修飾には、バインド変数、定数、文字列、日付の演算など、任意の式を使用できます。カーソルをオープンし、スナップショット値(タイムスタンプまたはSCN)を動的にバインドし、表を修飾できます。
関連項目
|
この項の内容は、次のとおりです。
この項では、フラッシュバック問合せを使用する利点について説明します。
レポート生成ツールなど、問合せのみを行うパッケージ・アプリケーションは、ログオン・トリガーを使用してフラッシュバック問合せモードで実行できます。アプリケーションは、コードを変更することなく、透過的に実行できます。フラッシュバック問合せ時の、データベースの一貫したバージョンがあるため、アプリケーションのすべての制約は意識することなく確実に遵守されます。
アプリケーションにリカバリ処理が必要な場合は、SCNを保存し、そのSCNにフラッシュバックしてリカバリを実行できます。これは、アプリケーションが明示的なバージョニングを実行した場合に、データ・セットを保存して後にリストアするよりもはるかに容易で高速です。フラッシュバック問合せを使用すると、明示的なバージョニングによって発生するロギングのコストを排除できます。
フラッシュバック問合せはオンラインで行う操作です。オブジェクトがフラッシュバック問合せ内で問合せを受けている間、他のセッションから同時実行されるDMLや問合せが許可されます。それらの操作のスピードは影響を受けません。さらに、別のセッションが同じオブジェクトの異なる時間やSCNに同時にフラッシュバックすることもできます。フラッシュバック問合せ自体のスピードは、問合せが過去にさかのぼる時間の長さに比例して適用されるUNDOの量に依存します。
ユーザー側では、適切な保存間隔の設定や必要な権限の保持などの他に、追加の管理は必要ありません。また、過去のバージョンは必要に応じて自動的に構成されるため、追加のロギングを実施する必要もありません。
この項では、フラッシュバック問合せの用途について説明します。
偶然、表から重要な行を数行削除してしまい、それをリカバリするとします。修復するには、時間をさかのぼって削除した行を探し、それを現在の表に挿入します。
過去に、メールを削除している場合があります。フラッシュバック問合せを使用すると、時間をさかのぼって削除したメールを現在のメッセージ・ボックスに再度挿入して、この削除したメールをリストアできます。
以前の口座残高を、特定の日付で表示できます。
パッケージ・アプリケーション(レポート生成ツールなど)では、アプリケーション・ロジックに変更を加えることなく、フラッシュバック問合せを利用できます。ユーザーに対して、特定の時間またはSCNにおけるデータベースの一貫したバージョンが示されるため、アプリケーションで必要となる制約はすべて確実に遵守されます。
また、監査情報の検査後にフラッシュバック問合せを使用して、データのビフォア・イメージを確認できます。DSS環境では、OLTPシステムから一貫した時点でのデータを抽出するために使用できます。
|
![]() Copyright © 1993, 2008 Oracle Corporation. All Rights Reserved. |
|