Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

START TRANSACTION

トランザクションを開始します。

Synopsis

START TRANSACTION [%COMMITMODE commitmode]

START TRANSACTION [transactionmodes]

引数

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 のみです。

概要

START TRANSACTIONトランザクションを開始します。START TRANSACTION は、現在のコミット・モードの設定に関係なく、即座にトランザクションを開始します。START TRANSACTION で開始したトランザクションは、現在のコミット・モードの設定に関係なく、明示的な COMMIT または ROLLBACK を発行して終了する必要があります。

START TRANSACTION を使用するかどうかは任意です。

  • プロセスがデータのクエリのみを行っている場合 (SELECT 文)、SET TRANSACTION を使用して ISOLATION LEVEL を設定できます。START TRANSACTION は不要です。

  • プロセスがデータを変更中の場合、START TRANSACTION を発行して SQL トランザクションを明示的に開始する必要があるかどうかは、プロセスの現在のコミット・モード設定 (自動コミット設定とも呼ばれます) によって決定されます。現在のプロセスのコミット・モードが IMPLICIT または EXPLICIT の場合は、START TRANSACTION を発行するかどうかは任意です。START TRANSACTION を省略した場合、データ変更操作 (DELETEUPDATEINSERT、または TRUNCATE TABLE) を呼び出すと、システムは自動的にトランザクションを開始します。START TRANSACTION を指定すると、トランザクションは即座に開始され、明示的な COMMIT または ROLLBACK で終了する必要があります。

START TRANSACTION はトランザクションを開始すると、$TLEVEL トランザクション・レベル・カウンタを 0 から 1 にインクリメントし、トランザクションが進行中であることを示します。また、%INTRANSACTION 文によって設定されている SQLCODE をチェックして、トランザクションが進行中かどうかを確認することもできます。トランザクションが進行中の場合、START TRANSACTION を発行しても $TLEVEL または %INTRANSACTION には効果がありません。

Caché SQL では、入れ子になったトランザクションはサポートされません。トランザクションが既に進行中の場合、START TRANSACTION を発行してもトランザクションを開始せず、エラー・コードも返しません。Caché SQL では、トランザクションの部分的なロールバックを許可するセーブポイントがサポートされています。

トランザクションが進行中ではない場合に SAVEPOINT 文を発行すると、SAVEPOINT はトランザクションを開始します。ただし、この方法でトランザクションを開始することはお勧めしません。

トランザクションの動作が正常完了できなかった場合は、SQLCODE -400 が発行されます。

%BEGTRANS (非推奨)

%BEGTRANS 文は、機能的には、引数なしの START TRANSACTION と同じです。%BEGTRANS は引数を取ることができないので、非推奨と見なされます。すべての新しい SQL プログラム・コードで START TRANSACTION を使用してください。

パラメータ設定

必要に応じて、START TRANSACTION を使用して、パラメータを設定することができます。指定したパラメータ設定は、即座に有効になります。ただし、START TRANSACTION で開始したトランザクションは、commitmode パラメータの設定に関係なく、明示的な COMMIT または ROLLBACK で終了する必要があります。パラメータ設定は、現在のプロセスの間または明示的にリセットされるまで、有効になります。トランザクションの最後に、自動的に既定値にリセットされることはありません。

単一の START TRANSACTION 文を使用して、commitmode パラメータまたは transactionmodes パラメータを設定できますが、両方を設定することはできません。両方を設定するには、SET TRANSACTION および START TRANSACTION または 2 つの START TRANSACTION 文を発行します。最初の START TRANSACTION は、トランザクションを開始します。

START TRANSACTION を発行した後に、トランザクション中に別の START TRANSACTIONSET TRANSACTION、またはメソッド呼び出しを発行して、これらのパラメータ設定を変更できます。commitmode パラメータを変更しても、現在のトランザクションを明示的な COMMIT または ROLLBACK で終了するという要件がなくなることはありません。

SET TRANSACTION 文を使用すると、トランザクションを開始せずに commitmode パラメータまたは transactionmodes パラメータを設定できます。また、これらのパラメータは、トランザクション内部または外部のメソッド呼び出しを使用しても設定できます。

%COMMITMODE

%COMMITMODE キーワードを使用すると、現在のプロセスでトランザクションの開始とコミットの自動化を指定できます。START TRANSACTION %COMMITMODE は、現在のプロセスの今後すべてのトランザクションのコミット・モードの設定を変更します。START TRANSACTION 文で開始されたトランザクションには効果がありません。現在のまたは設定されているコミット・モードに関係なく、START TRANSACTION は即座にトランザクションを開始し、このトランザクションは、明示的な COMMIT または ROLLBACK を発行して終了する必要があります。

使用可能な %COMMITMODE のオプションは以下のとおりです。

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

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

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

SetAutoCommit()Opens in a new tab メソッド呼び出しを使用することで、ObjectScript で %COMMITMODE を設定できます。使用可能なメソッドの値は、0 (NONE)、1 (IMPLICIT)、および 2 (EXPLICIT) です。

ISOLATION LEVEL

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

  • READ UNCOMMITTED は、すべての変更分がクエリ・アクセスで即座に使用できることを示します。これには、その後ロールバックされる可能性のある変更が含まれます。READ UNCOMMITTED では、クエリは同時挿入または更新プロセスを待機せずに結果を返すため、ロック・タイムアウト・エラーにより失敗することはありません。ただし、READ UNCOMMITTED の結果にはコミットされていない値が含まれる場合があります。挿入または更新操作が部分的にしか完了していないため、これらの値は内部的に不整合となり、その後ロールバックされる可能性があります。クエリ・プロセスが明示的なトランザクション内にない場合、またはトランザクションで ISOLATION LEVEL が指定されない場合、READ COMMITTED が既定となります。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 または $SYSTEM.SQL.SetIsolationMode(1) の設定により、SQL はコミットされたデータへの変更のみを取得できます。ただし、この規則には以下のような重要な例外があります。

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

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

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

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

Note:

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

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

有効な ISOLATION LEVEL

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

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

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

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

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

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

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

ObjectScript と SQL のトランザクション

ObjectScript と SQL のトランザクション・コマンドは完全に互換性があり、置き換え可能ですが、以下の例外があります。

ObjectScript TSTART と SQL START TRANSACTION はどちらも、トランザクションが進行中でない場合にトランザクションを開始します。ただし、START TRANSACTION では、入れ子になったトランザクションはサポートされません。そのため、入れ子になったトランザクションが必要な場合 (または必要になる可能性がある場合) には、トランザクションを TSTART で始めることをお勧めします。SQL 標準との互換性が必要な場合は、START TRANSACTION を使用してください。

ObjectScript トランザクション処理は、入れ子になったトランザクションを限定的にサポートします。SQL トランザクション処理はトランザクション内のセーブポイントをサポートします。

トランザクションに SQL データ変更文が含まれる場合、SQL の START TRANSACTION 文でトランザクションが開始され、COMMIT 文でコミットされます (これらの文は、%COMMITMODE 設定の設定によって明示的または暗黙的になります)。TSTART/TCOMMIT を入れ子にして使用するメソッドは、トランザクションを開始するものでなければ、トランザクションに組み込むことができます。メソッドとストアド・プロシージャは、通常、設計でトランザクションの主要なコントローラにならない限り、SQL トランザクション制御文を使用しません。ストアド・プロシージャは、独自のトランザクション制御モデルの ODBC/JDBC から呼び出されるため、通常 SQL トランザクション制御文を使用しません。

以下の埋め込み SQL の例では、2 つの START TRANSACTION 文を使用して、トランザクションを開始し、そのパラメータを設定しています。最初の START TRANSACTION では、トランザクションを開始し、コミット・モードを設定して、$TLEVEL トランザクション・レベル・カウンタをインクリメントしています。2 番目の START TRANSACTION では、現在のトランザクションのクエリ読み取り操作に分離モードを設定しますが、トランザクションは既に開始されているため、$TLEVEL をインクリメントしていません。SAVEPOINT 文 は $TLEVEL をインクリメントします。

    WRITE !,"Transaction level=",$TLEVEL
  &sql(START TRANSACTION %COMMITMODE EXPLICIT)
    WRITE !,"Start transaction commit mode, SQLCODE=",SQLCODE
    WRITE !,"Transaction level=",$TLEVEL
  &sql(START TRANSACTION ISOLATION LEVEL READ COMMITTED)
    WRITE !,"Start transaction isolation mode, 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