ヘッダーをスキップ
Oracle Rdb SQLリファレンス・マニュアル
リリース7.2
E06178-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 


SQL> SET TRANSACTION READ ONLY ISOLATION LEVEL READ COMMITTED;
%SQL-F-SETTRASLI, SET TRANSACTION statement specifies conflicting options
SQL> -- or
SQL> SET TRANSACTION READ ONLY ISOLATION LEVEL REPEATABLE READ;
%SQL-F-SETTRASLI, SET TRANSACTION statement specifies conflicting options

  • FOR UPDATE ONLYカーソルを使用して行が読み取られる場合、この行は排他的にロックされ、COMMIT文またはROLLBACK文が発行されるまでこの結果は変更されません。

  • 特定の共有モードを使用して表を予約すると、その共有モードにより、指定した分離レベルで暗黙的に定義された動作がオーバーライドされる場合があります。たとえば、ノンリピータブル・リードは、保護された取得用として明示的に予約された表では常に防止されています。この場合、分離レベルREPEATABLE READにより、同時実行性が別途確保されることはありません。一部の表が保護された取得用として予約されており、他の表が同時取得用として予約されている場合、同時取得用として予約されている表ではノンリピータブル・リードの防止は試行されません。
    したがって、共有モードのロックと分離レベル間の相互作用を使用することにより、特定の目標を達成できます。ただし、Oracle Rdbでは、アプリケーションでこのような複雑なレベルは使用しないことをお薦めします。

  • SET TRANSACTION文は、1つのトランザクションの指定と開始の両方を行う実行可能文です。ホスト言語ソース・ファイルまたはSQL言語モジュールには、複数のSET TRANSACTION文を含めることができます(第3章を参照)。SET TRANSACTION文には、次の利点があります。

  • SET TRANSACTION文とは対照的に、DECLARE TRANSACTION文は実行可能文ではないため、トランザクションは開始されません。(DECLARE TRANSACTION文での宣言が有効になるのは、暗黙的トランザクションの開始時、つまり、DECLARE TRANSACTION文、COMMIT文またはROLLBACK文に続く最初の実行可能なデータ操作文またはデータ定義文の実行時です。)
    ホスト言語ソース・ファイルまたはSQLモジュール言語ソース・ファイルには、1つのDECLARE TRANSACTION文のみを指定できます。プログラムで(SET TRANSACTION文を使用せずに)DECLARE TRANSACTION文を使用してトランザクション特性を変更する唯一の方法は、SQL文を個々のソース・ファイルに組み込み、ファイルごとに異なるDECLARE TRANSACTION文を指定する方法です。
    DECLARE TRANSACTION文には、次の利点があります。

  • 分散トランザクション・マネージャを明示的にコールすると、アプリケーションにおける複数のデータベースを対象としたトランザクションの実行を制御できます。詳細は、『Oracle Rdb7 Guide to Distributed Transactions』を参照してください。

  • データベース・ユーザーが別のユーザーのデータベースの状態を破損できないようにするために、SQLでは、次の措置が適用されます。


    トランザクション全体が正常にコミットされるまでは、データベースを変更するトランザクションのいずれの部分も完了しません。特に、トランザクションが正常にコミットされるまでは、トランザクション中の任意の時点においてデッドロックが発生する可能性があります。プログラムでは、読取り専用モードまたは排他モードで開始されたトランザクションを除き、各データベース操作後にDEADLOCKについて検証する必要があります。また、プログラムでトランザクションのNOWAITが宣言されている場合、LOCK_CONFLICTについて検証する必要があります。
    通常、デッドロックまたはロック競合からリカバリするための最善の方法は、ROLLBACK文を使用し、トランザクションを再開する方法です。
    データを共有モードで挿入または更新する場合、この表で索引の索引ノードがロックされる場合があります。この機能により、新規データのためにこれらの索引ノードを更新できるようになります。このプロセスはしばしばデッドロックが発生する原因となります。

  • 読取り専用トランザクションは本質的に制限されているため、次のような制限が課されます。

  • マルチスキーマ・データベースで別名を使用するには、例4に示すように、ANSI/ISO引用ルールを有効にして、デリミタ付き識別子を作成する必要があります。デリミタ付き識別子の詳細は、第2.2.11項を参照してください。

  • キャリーオーバー・ロックの更新が表レベルで有効にされたプロセスの場合、表をPROTECTED READモードまたはPROTECTED WRITEモードで予約すると、同時実行性に関する問題が発生する可能性があります。表レベルでのキャリーオーバー・ロックは、RDMS$AUTO_READY論理名を定義することによって設定されます。この論理名とキャリーオーバー・ロックの詳細は、『Oracle Rdb7 Guide to Database Performance and Tuning』を参照してください。

  • データベースに長期間アタッチされているサーバー・プロセスがアプリケーションに使用されるためにスナップショット・ファイルが大きくなりすぎる場合、事前起動済トランザクションの無効化を検討してください。(事前起動済トランザクションはデフォルトでは有効です。)事前起動済トランザクションを無効にするには、ATTACH文、CONNECT文、DECLARE ALIAS文、CREATE DATABASE文およびIMPORT文のPRESTARTED TRANSACTIONS ARE OFF句を使用します。詳細は、「ATTACH文」および『Oracle Rdb7 Guide to Database Performance and Tuning』を参照してください。

  • ストアド・プロシージャでSET TRANSACTION文をRESERVING表句またはEVALUATING制約句とともに使用する場合、指定した表または制約に対するプロシージャの依存性が確立されます。ストアド・プロシージャの無効化を切り替える文のリストは、「CREATE MODULE文」を参照してください。
    ストアド・プロシージャ依存性の種類およびメタデータ変更によるストアド・プロシージャ無効化の詳細は、『Oracle Rdb7 Guide to SQL Programming』を参照してください。

  • SET TRANSACTION EVALUATING AT VERB TIME文は、NOT DEFERRABLE制約には使用できません。

  • ビューによって参照される各表は、この表がSET TRANSACTION文で明示的に予約されていないかぎり、自動的にビューの予約時と同じモードで予約されます。READ ONLYトランザクションの場合、すべての表は読取り専用としてアクセスされます。

  • 制約またはトリガーによって参照される表は、明示的なSET TRANSACTION文によってより上位のモードで予約されていないかぎり、SHARED READモードで予約されます。

  • トリガーによって更新される表は、明示的なSET TRANSACTION文によってより上位のモードで予約されていないかぎり、SHARED WRITEモードで予約されます。SET TRANSACTION文によって表がREADアクセス用としてすでに予約されている場合、トリガーがロードされるとエラーが返されます。

  • READ ONLYトランザクションが進行中である場合、トリガーも制約もアクティブではありません。トリガーおよび制約は更新操作用としてのみロードされるため、この状況下では何も自動的に予約されません。

  • COMPUTED BY式、AUTOMATIC式またはDEFAULT式によって参照される表は、参照元の文によってSHARED READモードで暗黙的に予約されます。表がストアド・ファンクションによって間接的にアクセスされる場合、LOCK TABLEを使用して表を予約します。

  • 記憶域マップが表にないか、垂直にパーティション化された記憶域マップが表にある場合(STORE COLUMNS句が使用されている場合)、パーティション句は使用できません。索引および記憶域マップに同じSTORE句がある場合、これらは両方とも同じパーティション番号のリストを使用してロックされます。

  • PARTITION句を使用するには、データベースおよびアプリケーションを慎重に設計する必要があります。異なるパーティション化キーまたは異なる値の範囲を使用して索引がパーティション化されている場合、複数のパーティションにわたって更新を行うと、同時更新プロセス間でデッドロックや他のロック競合が発生する可能性があります。

  • デフォルトでは、EXCLUSIVEアクセス用として表を予約するトランザクションにおいて、LIST(セグメント化された文字列)領域は排他アクセス用として予約されません。通常、LIST領域は多くの表によって共有されるため、デフォルトでは、他の表への更新を許可するためにSHAREDアクセスが想定されます。
    つまり、インポート操作を実行する場合や、EXCLUSIVEアクセス用として予約されている表がアプリケーションによって更新される場合、スナップショットの記憶域(.snp)が大きくなることがあります。これは、SHARED WRITEモードの使用時にデフォルトで実行されるLIST領域に対するI/Oが原因です。
    ただし、SQL ATTACH文またはIMPORT文を使用してデータベースにアタッチする場合、RESTRICTED ACCESS句を指定すると、すべての記憶域がEXCLUSIVEモードでアクセスされます。LIST記憶域に対して大量のI/Oを実行する場合、この句を使用してスナップショットのI/Oとそれに関連するオーバーヘッドを削減します(たとえば、データベースを再構築する場合や、LIST OF BYTE VARYING列およびデータが含まれる大きい表を削除する場合などがあります)。


    例1: 読取り専用トランザクションの開始


    SQL> SET TRANSACTION READ ONLY;
    

    この文の場合、データベースからデータを読み取ることはできますが、データを挿入または更新することはできません。データを取得すると、トランザクションが開始されたときに存在していたデータベース・レコードが表示されます。これ以降に行われたデータベースに対する更新は表示されません。

    例2: SET TRANSACTION文を使用した特定の表の予約

    次の文では、トランザクションで各表に対して目的のアクションを指定できます。


    SQL> ATTACH 'FILENAME mf_personnel';
    SQL> SET TRANSACTION READ WRITE RESERVING
    cont>      EMPLOYEES FOR PROTECTED WRITE,
    cont>      JOBS, SALARY_HISTORY FOR SHARED READ;
    

    このトランザクションにより、他の2つの表(JOBSおよびSALARY_HISTORY)で見つかった値に基づいてEMPLOYEES表を更新するとします。

    • このトランザクションではEMPLOYEES表を更新する必要があるため、EMPLOYEESは、保護された書込みアクセス用として用意されています。

    • JOBS表およびSALARY_HISTORY表からは値の読取りのみが行われるため、書込みアクセスまたは保護された書込みアクセスは必要ありません。ただし、トランザクションでレコードを更新することが目的であるため、読取り専用トランザクションは適切ではありません。

    例3: SET TRANSACTION文での複数のデータベースの指定

    1つのトランザクションで複数のデータベースにアクセスできます。この例では、この機能の利点について説明します。

    読取り専用トランザクションではデータのスナップショット・バージョンが使用されるため、アプリケーションで取得されるデータには古い値が含まれる場合があります。これは、読取り/書込みトランザクションを使用する別のトランザクションによって表が更新されている可能性があるためです。

    スナップショット・ファイルは、他のプログラムによって更新されているデータベース行の以前のイメージを表します。最新のデータが必要な場合、両方のデータベースに対して読取り/書込みアクセスを指定し、共有読取りモードを組み込んで他のユーザーがデータベースの1つを読み取るのを許可する必要があります。この方法により、更新中にデータ整合性を保持するとともに、読取り対象のデータベースからのデータの同時取得を許可できます。

    ただし、読取り/書込みトランザクションを設定する場合、可能な同時アクセス数が読取り専用アクセスよりも少なくなります。このため、読取り/書込みトランザクションを使用するのは必要な場合のみにしてください。

    SET TRANSACTION文の複数データベース機能を使用する前に、アクセス対象の各データベースを指定するDECLARE ALIAS文を発行する必要があります。DECLARE ALIAS文には、別名を含める必要があります。たとえば、次のDECLARE ALIAS文では、更新アプリケーションに必要な2つのデータベースを識別しています。


    EXEC SQL
    DECLARE DB1 ALIAS FOR FILENAME PERSONNEL;
    END EXEC
    
    EXEC SQL
    DECLARE DB2 ALIAS FOR FILENAME benefits;
    END EXEC
    

    PERSONNELデータベースではEMPLOYEES表の読取りのみが必要ですが、BENEFITSデータベースでは2つの表(TUITIONおよびSTATUS)の値を変更する必要があるため、更新プログラムには、次のSET TRANSACTION文を含めることができます。


    EXEC SQL  SET TRANSACTION
                 ON DB1 USING ( READ ONLY
                   RESERVING DB1.EMPLOYEES FOR SHARED READ )
                AND
                 ON DB2 USING ( READ WRITE
                   RESERVING DB2.TUITION FOR SHARED WRITE
                             DB2.STATUS  FOR SHARED WRITE )
    
    END EXEC
    

    例4: SET TRANSACTION文でのマルチスキーマ・データベースの指定

    アクセスするデータベースの1つがマルチスキーマ・データベースである場合、デリミタ付き識別子を使用してこれを指定する必要があります。次の例は、単一スキーマのpersonnelデータベースおよびマルチスキーマのcorporate_dataデータベースにアクセスする方法を示しています。表EMPLOYEESは、CORPORATE_DATAデータベース内のカタログADMINISTRATIONのスキーマPERSONNEL内にあります。


    SQL> ATTACH 'ALIAS CORP FILENAME corporate_data';
    SQL> ATTACH 'ALIAS PERS FILENAME personnel';
    SQL> SET QUOTING RULES 'SQL92';
    SQL> SET CATALOG '"CORP.ADMINISTRATION"';
    SQL> SET SCHEMA '"CORP.ADMINISTRATION".PERSONNEL';
    SQL> --
    SQL> SET TRANSACTION ON CORP USING (READ ONLY
    cont>    RESERVING "CORP.EMPLOYEES" FOR SHARED READ)
    cont>    AND ON PERS USING (READ WRITE RESERVING
    cont>    PERS.EMPLOYEES FOR SHARED WRITE);
    

    例5: SET TRANSACTION文での動詞実行時における評価の指定

    次の例は、EMPLOYEE_ID 00164の新規取得学位をDEGREES表に挿入する処理を示しています。新規学位であるMMEが評価されましたが、これは受入れ可能な学位コードではないため、エラー・メッセージが即時に返されています。


    SQL> ATTACH 'FILENAME personnel';
    SQL> SET TRANSACTION READ WRITE
    cont>   EVALUATING DEGREES_FOREIGN1 AT VERB TIME,
    cont>   DEGREES_FOREIGN2 AT VERB TIME,
    cont>   DEG_DEGREE_VALUES AT VERB TIME
    cont>   RESERVING DEGREES FOR PROTECTED WRITE,
    cont>   COLLEGES, EMPLOYEES FOR SHARED READ;
    SQL> SHOW TRANSACTION
    Transaction information:
        Statement constraint evaluation is off
    
    On the default alias
    Transaction characteristics:
            Read Write
            Evaluating constraint DEGREES_FOREIGN1 at verb time
            Evaluating constraint DEGREES_FOREIGN2 at verb time
            Evaluating constraint DEG_DEGREE_VALUES at verb time
            Reserving table DEGREES for protected write
            Reserving table COLLEGES for shared read
            Reserving table EMPLOYEES for shared read
    Transaction information returned by base system:
    a read-write transaction is in progress
      - updates have not been performed
      - transaction sequence number (TSN) is 153
      - snapshot space for TSNs less than 153 can be reclaimed
      - session ID number is 21
    SQL> INSERT INTO DEGREES
    cont>   (EMPLOYEE_ID, COLLEGE_CODE, YEAR_GIVEN,
    cont>    DEGREE, DEGREE_FIELD)
    cont> VALUES
    cont>   ('00164', 'PRDU',  1992,
    cont>   'MME',  'Mech Enging');
    %RDB-E-INTEG_FAIL, violation of constraint DEG_DEGREE_VALUES caused
    operation to fail
    -RDB-F-ON_DB, on database DISK1:[JONES.PERSONNEL]PERSONNEL.RDB;1
    SQL> ROLLBACK;
    

    例6: トランザクションでの分離レベルの明示的な設定

    この文では、データベースでのデータの読取りと書込みが可能です。また、トランザクションは、上位のデフォルト分離レベルであるSERIALIZABLEではなく、分離レベルREAD COMMITTEDで実行されるよう設定されています。


    SQL> SET TRANSACTION READ WRITE ISOLATION LEVEL REPEATABLE READ;
    

    例7: 索引の同時作成

    次の例は、共有データ定義用の表を予約する方法と、索引を作成する方法を示しています。


    SQL> SET TRANSACTION READ WRITE
    cont>    RESERVING EMPLOYEES FOR SHARED DATA DEFINITION;
    SQL> --
    SQL> CREATE INDEX EMP_LAST_NAME1 ON EMPLOYEES (LAST_NAME);
    SQL> --
    SQL> -- Commit the transaction immediately.
    SQL> --
    SQL> COMMIT;
    

    例8: パーティションの予約


    SQL> -- This example locks only the second partition of
    SQL> -- the EMPLOYEES table in exclusive write mode.
    SQL> -- The advantage of this is that the process can insert,
    SQL> --  update, or delete from this partition without writing
    SQL> -- to the snapshot (.snp) file, and in general, uses fewer
    SQL> --  resources for operations on the partition.
    SQL> SET TRANSACTION READ WRITE
    cont> RESERVING EMPLOYEES PARTITION (2) FOR EXCLUSIVE WRITE;
    

    例9: RESERVING句と列のDEFAULT値の相互作用

    この例では、表を(直接的または間接的に)参照するDEFAULT値とRESERVING句の相互作用について確認します。SET TRANSACTIONのRESERVING句により、トランザクションは、このトランザクション用としてリストされている表にのみ制限されます。

    制約、トリガー、COMPUTED BY句、AUTOMATIC句およびDEFAULT値によって直接参照される表は、SHARED READ用として暗黙的に予約されます。ただし、これらの定義によってストアド・ファンクションを介して表が間接的に参照される場合、この表は自動予約の対象とはみなされません。

    この例では、DEFAULT値を使用して、3つの異なるメカニズムおよびそのRESERVING句との相互作用を対比しています。この技術は、トリガーおよび制約などの他の定義にも適用できます。

    DEFAULT値は、データベースの有効なユーザーごとに1つの値が保持されるセカンダリ表(DEFAULTS)から導出されます。DEFAULTは、CURRENT_USERの値に基づいて取得されます。次の3つの表では、値は、直接フェッチされるか(SAMPLE_TABLE2)、ストアド・ファンクションを介してフェッチされています(SAMPLE_TABLE1およびSAMPLE_TABLE3)。

    SQLファンクションGET_DEFAULT3には、表を正しく予約できるようLOCK TABLE文が含まれています。この方法を使用すると、プログラマはトランザクションに対してRESERVING句をコーディングするときに必要な表を把握しなくて済むため、この方法を使用することをお薦めします。


    SQL> set dialect 'sql99';
    SQL>
    SQL> create table DEFAULTS
    cont>     (user_id      rdb$object_name primary key,
    cont>      valid_number integer);
    SQL> insert into DEFAULTS values ('SMITH', 100);
    1 row inserted
    SQL>
    SQL> create module UTL1
    cont>     function GET_DEFAULT1 ()
    cont>     returns integer
    cont>     not deterministic;
    cont>     return (select valid_number from DEFAULTS
    cont>             where user_id = CURRENT_USER);
    cont> end module;
    SQL>
    SQL> create table SAMPLE_TABLE1
    cont>     (id         integer identity,
    cont>      quantity   integer
    cont>                 default GET_DEFAULT1 ()
    cont>     );
    SQL>
    SQL> create table SAMPLE_TABLE2
    cont>     (id         integer identity,
    cont>      quantity   integer
    cont>                 default (select valid_number from DEFAULTS
    cont>                          where user_id = CURRENT_USER)
    cont>     );
    SQL>
    SQL> create module UTL3
    cont>     function GET_DEFAULT3 ()
    cont>     returns integer
    cont>     not deterministic;
    cont>     begin
    cont>     lock table DEFAULTS for shared read mode;
    cont>     return (select valid_number from DEFAULTS
    cont>             where user_id = CURRENT_USER);
    cont>     end;
    cont> end module;
    SQL>
    SQL> create table SAMPLE_TABLE3
    cont>     (id         integer identity,
    cont>      quantity   integer
    cont>                 default GET_DEFAULT3 ()
    cont>     );
    SQL>
    SQL> commit;
    

    次のトランザクションは、この例で説明するように成功または失敗しています。


    SQL> /*
    ***> Fails because the module references a table that is not reserved
    ***> */
    SQL> set transaction read write
    cont>     reserving SAMPLE_TABLE1 for shared write;
    SQL> insert into SAMPLE_TABLE1 default values;
    %RDB-E-UNRES_REL, relation DEFAULTS in specified request is not a
    relation reserved in specified transaction
    SQL> rollback;
    SQL>
    SQL> /*
    ***> Succeeds because direct access to the table from the DEFAULT
    ***> is implicitly added to the reserving list as SHARED READ
    ***> */
    SQL> set transaction read write
    cont>     reserving SAMPLE_TABLE2 for shared write;
    SQL> insert into SAMPLE_TABLE2 default values;
    1 row inserted
    SQL> rollback;
    SQL>
    SQL> /*
    ***> Succeeds because the routine adds the table to the reserved
    ***> table list using LOCK TABLE.
    ***> */
    SQL> set transaction read write
    cont>     reserving SAMPLE_TABLE3 for shared write;
    SQL> insert into SAMPLE_TABLE3 default values;
    1 row inserted
    SQL> rollback;
    SQL>