Skip to main content

This documentation is for an older version of this product. See the latest version of this content.Opens in a new tab

SET TRANSACTION (SQL)

トランザクションのパラメータを設定します。

Synopsis

SET TRANSACTION [%COMMITMODE commitmode]

SET TRANSACTION [transactionmodes]

引数

引数 説明
%COMMITMODE commitmode オプション — トランザクションがデータベースにコミットされる方法を指定します。利用可能な値は、EXPLICIT、IMPLICIT、そして NONE です。既定は IMPLICIT です。
transactionmodes

オプション — トランザクションのアクセス・モードと分離モードを指定します。分離モード、アクセス・モード、またはコンマ区切りリストとして両方のモードの値を指定できます。

分離モードの有効な値は、ISOLATION LEVEL READ COMMITTED、ISOLATION LEVEL READ UNCOMMITTED、および ISOLATION LEVEL READ VERIFIED です。既定は、ISOLATION LEVEL READ UNCOMMITTED です。

アクセス・モードに有効な値は READ ONLY と READ WRITE です。アクセス・モード READ WRITE と互換性があるのは ISOLATION LEVEL READ COMMITTED のみです。

概要

SET TRANSACTION 文は、現在のプロセスの SQL トランザクションを管理するパラメータを設定します。これらのパラメータは、次のトランザクションの開始時に発効し、現在のプロセスの間、または明示的にリセットされるまでの間、有効となります。トランザクションの最後に、自動的に既定値にリセットされることはありません。

単一の SET TRANSACTION 文を使用して、commitmode パラメータまたは transactionmodes パラメータを設定できますが、両方を設定することはできません。

START TRANSACTION コマンドを使用しても同じパラメータを設定できます。このコマンドでは、パラメータの設定と新しいトランザクションの開始を両方実行することができます。メソッド呼び出しを使用しても、パラメータを設定することができます。

SET TRANSACTION ではトランザクションは開始されず、$TLEVEL トランザクション・レベル・カウンタもインクリメントされません。

SET TRANSACTION は、ダイナミック SQL (SQL シェルを含む) と埋め込み SQL で使用できます。

%COMMITMODE

%COMMITMODE キーワードを使用すると、トランザクションのコミットを自動的に実行するかどうかを指定できます。使用可能なオプションは以下のとおりです。

  • IMPLICIT : トランザクションの自動コミットをオンにする (既定)。プログラムがデータベース変更操作 (INSERTUPDATE、または DELETE) を発行すると、SQL はトランザクションを自動的に開始します。操作が正常に完了し、SQL が変更を自動的にコミットするか、操作がすべての行では正常に完了できず、SQL が操作全体を自動的にロールバックするまで、トランザクションは継続されます。各データベース操作 (INSERTUPDATE、または DELETE) は、個別のトランザクションを構成します。データベース操作の実行が成功すると、自動的にロールバックのジャーナルがクリアされ、ロックが解放され、$TLEVEL がデクリメントされます。COMMIT 文は必要ありません。これが既定の設定です。

  • EXPLICIT : トランザクションの自動コミットをオフにする。プログラムが最初のデータベース変更操作 (INSERTUPDATE、または DELETE) を発行すると、SQL はトランザクションを自動的に開始します。トランザクションは明示的に終了されるまで継続します。正常に終了したら、COMMIT 文を発行します。データベース変更操作が失敗したら、ROLLBACK 文を発行して、データベースをトランザクションが始まる前の時点に戻します。EXPLICIT モードでは、トランザクションあたりのデータベース操作の数は、ユーザ定義です。

  • NONE : トランザクション処理を自動化しない。START TRANSACTION 文で明示的に呼び出さない限り、トランザクションは開始されません。COMMIT 文または ROLLBACK 文を発行して、トランザクションを明示的に終了する必要があります。このため、データベース操作がトランザクションに含まれるかどうかと、トランザクション内のデータベース操作の数は、ユーザ定義です。

TRUNCATE TABLE は、自動的に開始されたトランザクション内では発生しません。TRUNCATE TABLE のジャーナリングおよびロールバックが必要な場合、明示的に START TRANSACTION を指定し、明示的な COMMIT または ROLLBACK で終わる必要があります。

現在のプロセスの %COMMITMODE 設定を確認するには、以下の ObjectScript の例のように、GetOption("AutoCommit")Opens in a new tab メソッドを使用します。

  SET stat=$SYSTEM.SQL.Util.SetOption("AutoCommit",$RANDOM(3),.oldval)
  IF stat'=1 {WRITE "SetOption failed:" DO $System.Status.DisplayError(qStatus) QUIT}
    SET x=$SYSTEM.SQL.Util.GetOption("AutoCommit")
  IF x=1 {
    WRITE "%COMMITMODE IMPLICIT (default behavior):",!,
          "each database operation is a separate transaction",!,
          "with automatic commit or rollback" }
  ELSEIF x=0 {
    WRITE "%COMMITMODE NONE:",!,
          "No automatic transaction support",!,
          "You must use START TRANSACTION to start a transaction",!,
          "and COMMIT or ROLLBACK to conclude one" }
  ELSE { 
    WRITE "%COMMITMODE EXPLICIT:",!,
          "the first database operation automatically",!,
          "starts a transaction; to end the transaction",!,
          "explicit COMMIT or ROLLBACK required" }

%COMMITMODE は、SetOption()Opens in a new tab メソッドを SET status=$SYSTEM.SQL.Util.SetOption("AutoCommit",intval,.oldval) のように使用して、ObjectScript 内で設定できます。使用可能なメソッドの値は、0 (NONE)、1 (IMPLICIT)、および 2 (EXPLICIT) です。

ISOLATION LEVEL

クエリを発行しているプロセスの ISOLATION LEVEL を指定します。ISOLATION LEVEL オプションを使用すると、進行中の変更に対してクエリが読み取りアクセスできるようにするかどうかを指定できます。別の同時プロセスがテーブルに対して挿入または更新を行っており、それらのテーブルへの変更がトランザクション内である場合、それらの変更は進行中で、ロールバックされる可能性があります。テーブルのクエリを行っているプロセスの ISOLATION LEVEL を設定することで、これらの進行中の変更をクエリ結果に含めるか排除するかを指定できます。

  • READ UNCOMMITTED は、すべての変更分がクエリ・アクセスで即座に使用できることを示します。これには、その後ロールバックされる可能性のある変更が含まれます。READ UNCOMMITTED では、クエリは同時挿入または更新プロセスを待機せずに結果を返すため、ロック・タイムアウト・エラーにより失敗することはありません。ただし、READ UNCOMMITTED の結果にはコミットされていない値が含まれる場合があります。挿入または更新操作が部分的にしか完了していないため、これらの値は内部的に不整合となり、その後ロールバックされる可能性があります。クエリ・プロセスが明示的なトランザクション内にない場合、またはトランザクションで ISOLATION LEVEL が指定されない場合、READ UNCOMMITTED が既定となります。READ UNCOMMITTED は、READ WRITE アクセスと互換性がありません。同じ文で両方を指定すると、SQLCODE -92 エラーが発生します。

  • READ VERIFIED は、その他のトランザクションのコミットされていないデータがすぐに使用可能であり、ロックが実行されないことを示しています。これには、その後ロールバックされる可能性のある変更が含まれます。ただし、READ UNCOMMITTED とは異なり、READ VERIFIED トランザクションは、クエリ条件を満たさない出力となるコミットされていないデータや新たにコミットされたデータによって無効にされる可能性があるすべての条件を再確認します。この条件の再確認のため、READ VERIFIED は READ UNCOMMITTED よりも正確ですが、効率性は劣ります。READ VERIFIED は、条件による確認が行われるデータに対する同期更新が行われる可能性がある場合のみ使用してください。READ VERIFIED は、READ WRITE アクセスと互換性がありません。同じ文で両方を指定しようとすると、SQLCODE -92 エラーになります。

  • READ COMMITTED は、コミットされた変更分のみがクエリ・アクセスで使用できることを示します。これにより、実行されている変更のグループではなく、後にロールバックできる変更のグループの間で、クエリをデータベース内で一貫性のある状態で実行できます。要求されたデータは変更されているが、コミット (またはロールバック) されていない場合、クエリはトランザクションが完了するまで待機します。このデータが使用可能になるまで待機している間にロック・タイムアウトが発生した場合、SQLCODE -114 エラーが発行されます。

READ UNCOMMITTED と READ VERIFIED の違い

以下の例では、READ UNCOMMITTED と READ VERIFIED の違いが示されています。

SELECT Name,SSN FROM Sample.Person WHERE Name >= 'M' 

クエリ・オプティマイザは、まず、Name インデックスから >= 'M' の条件を満たす名前を含むすべての RowID を収集する選択を行う場合があります。収集後、出力用の Name フィールドと SSN フィールドを取得するために、Person テーブルへのアクセスが行われます (一度に 1 つの RowID)。同時に実行されている更新トランザクションにより、クエリによるインデックスからの RowID の収集とテーブルへの行単位のアクセスの間に、'Smith' から 'Abel' までの RowID 72 の Person の Name フィールドが変更される可能性があります。この場合、インデックスからの RowID の収集に Name >= 'M' の条件を満たさなくなった行の RowID が含まれます。

READ UNCOMMITTED のクエリ処理は、Name >= 'M' の条件がインデックスによって満たされていることを前提としており、インデックスから収集された RowID ごとにテーブル内にある Name を出力します。したがって、この例では、条件を満たさない 'Abel' の Name が含まれる行が出力されます。

READ VERIFIED のクエリ処理は、インデックスによってこれまで満たされていた条件に属する出力 (Name) 用のテーブルからフィールドを取得していることを示し、インデックスが検証された時点からフィールド値が変更されている場合に条件を再確認します。再確認時、行が条件を満たさなくなったことを示し、出力からそれを除外します。 出力で必要となる値のみ条件の再確認が行われます。この例において、SELECT SSN FROM Person WHERE Name >= 'M' は、RowID 72 の行を出力します。

READ COMMITTED に対する例外

コミットされた ISOLATION LEVEL 読み取りが有効な場合、ISOLATION LEVEL READ COMMITTED の設定により、または SetOption()Opens in a new tab メソッドを SET status=$SYSTEM.SQL.Util.SetOption("IsolationMode",1,.oldval) のように使用して、SQL はコミットされたデータへの変更のみを取得できます。ただし、この規則には以下のような重要な例外があります。

  • 行を削除したトランザクションが進行中で、その削除がその後ロールバックされる可能性があっても、削除された行がクエリによって返されることはありません。ISOLATION LEVEL READ COMMITTED では、挿入と更新は一貫性のある状態ですが、削除は一貫性のある状態ではありません。

  • クエリに集約関数が含まれる場合、指定された ISOLATION LEVEL に関係なく、集約結果によりデータの現在の状態が返されます。そのため、進行中の (その後ロールバックされる可能性がある) 挿入と更新は、集約結果に含まれます。進行中の (その後ロールバックされる可能性がある) 削除は、集約結果に含まれません。これは、集約操作ではテーブルの多数の行のデータにアクセスする必要があるためです。

  • DISTINCT 節または GROUP BY 節を含む SELECT クエリは、ISOLATION LEVEL 設定による影響を受けません。これらの節のいずれかを含むクエリは、データの現在の状態を返します。それには、その後ロールバックされる可能性のある進行中の変更が含まれます。これは、これらのクエリ操作では、テーブルの多数の行のデータにアクセスする必要があるためです。

  • %NOLOCK キーワードを使用するクエリ

Note:

InterSystems IRIS で ECP (Enterprise Cache Protocol) を実装して READ COMMITTED を使用した場合、READ UNCOMMITTED と比べてパフォーマンスが著しく低下する場合があります。開発者は ECP を含むトランザクションを定義する際に、READ UNCOMMITTED を使用して優れたパフォーマンスを得るか、READ COMMITTED を使用して高いデータの精度を得るかを十分に検討する必要があります。

詳細は、"InterSystems SQL の使用法" の “データベースの変更” の章にある "トランザクション処理" を参照してください。

有効な ISOLATION LEVEL

SET TRANSACTION (トランザクションを開始しない)、START TRANSACTION (分離モードを設定してトランザクションを開始)、または SetOption("IsolationMode")Opens in a new tab メソッド呼び出しを使用して、プロセスの ISOLATION LEVEL を設定できます。

指定された ISOLATION LEVEL は、SET TRANSACTIONSTART TRANSACTION、または SetOption("IsolationMode")Opens in a new tab メソッド呼び出しによって明示的にリセットされるまで有効です。COMMIT または ROLLBACK はデータの変更にのみ有効で、データ・クエリの変更には有効でないため、COMMIT または ROLLBACK の操作は ISOLATION LEVEL の設定に影響を与えません。

クエリの開始時に有効になっている ISOLATION LEVEL は、クエリ中も有効なままになります。

現在のプロセスの ISOLATION LEVEL を判別するには、GetOption("IsolationMode")Opens in a new tab メソッド呼び出しを使用します。また、現在のプロセスの分離モードを設定するには、SetOption("IsolationMode")Opens in a new tab メソッド呼び出しを使用します。これらのメソッドでは、READ UNCOMMITTED (既定) を 0、READ COMMITTED を 1、READ VERIFIED を 3 に指定します。他の数値を指定すると、分離モードが変更されません。分離モードを現在の分離モードに設定すると、エラーまたは変更は発生しません。これらのメソッドの使用法を以下の例に示します。

   WRITE $SYSTEM.SQL.Util.GetOption("IsolationMode")," default",!
   &sql(START TRANSACTION ISOLATION LEVEL READ COMMITTED,READ WRITE)
   WRITE $SYSTEM.SQL.Util.GetOption("IsolationMode")," after START TRANSACTION",!
   DO $SYSTEM.SQL.Util.SetOption("IsolationMode",0,.stat)
   IF stat=1 {
     WRITE $SYSTEM.SQL.Util.GetOption("IsolationMode")," after IsolationMode=0 call",! }
   ELSE { WRITE "Set IsolationMode error" }
   &sql(COMMIT)

分離モードとアクセス・モードは、常に互換性がある必要があります。以下の例のように、アクセス・モードを変更する場合は、分離モードを変更します。

   WRITE $SYSTEM.SQL.Util.GetOption("IsolationMode")," default",!
   &sql(SET TRANSACTION ISOLATION LEVEL READ COMMITTED,READ WRITE)
   WRITE $SYSTEM.SQL.Util.GetOption("IsolationMode")," after SET TRANSACTION",!
   &sql(START TRANSACTION READ ONLY)
   WRITE $SYSTEM.SQL.Util.GetOption("IsolationMode")," after changing access mode",!
   &sql(COMMIT)

以下の埋め込み SQL の例では、2 つの SET TRANSACTION 文を使用して、トランザクション・パラメータを設定しています。SET TRANSACTION では、トランザクション・レベル ($TLEVEL) がインクリメントされないことに注意してください。START TRANSACTION コマンドでトランザクションを開始して、$TLEVEL をインクリメントします。

  &sql(SET TRANSACTION %COMMITMODE EXPLICIT)
    WRITE !,"Set transaction commit mode, SQLCODE=",SQLCODE
    WRITE !,"Transaction level=",$TLEVEL
  &sql(SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED)
    WRITE !,"Set transaction isolation mode, SQLCODE=",SQLCODE
    WRITE !,"Transaction level=",$TLEVEL
  &sql(START TRANSACTION)
    WRITE !,"Start transaction, SQLCODE=",SQLCODE
    WRITE !,"Transaction level=",$TLEVEL
  &sql(SAVEPOINT a)
    WRITE !,"Set Savepoint a, SQLCODE=",SQLCODE
    WRITE !,"Transaction level=",$TLEVEL
  &sql(COMMIT)
    WRITE !,"Commit transaction, SQLCODE=",SQLCODE
    WRITE !,"Transaction level=",$TLEVEL

関連項目

FeedbackOpens in a new tab