トランザクションとロック
Native SDK for .NET は、InterSystems IRIS トランザクション・モデルを使用するトランザクション・メソッドとロック・メソッドを提供します。これについて、以下のセクションで説明します。
-
トランザクションの制御 — トランザクションの開始、入れ子、ロールバック、およびコミットの方法について説明します。
-
並行処理の制御 — さまざまなロック・メソッドの使用法について説明します。
Native SDK トランザクション・モデルを ADO.NET/SQL トランザクション・モデルと混在させないでください。
-
トランザクション内で Native SDK コマンドのみを使用する場合は、常に Native SDK トランザクション・メソッドを使用する必要があります。
-
トランザクション内で Native SDK コマンドと ADO.NET/SQL コマンドの組み合わせを使用する場合は、自動コミットをオフにした後、常に Native SDK トランザクション・メソッドを使用する必要があります。
-
トランザクション内で ADO.NET/SQL コマンドのみを使用する場合は、常に SQL トランザクション・メソッドを使用することも、自動コミットをオフにした後、常に Native SDK トランザクション・メソッドを使用することもできます。
-
同じアプリケーションで両方のモデルを使用できますが、トランザクションが一方のモデルでまだ実行されている間に、トランザクションをもう一方のモデルで開始しないように注意してください。
トランザクションの制御
ここで説明したメソッドは、標準の ADO.NET/SQL トランザクション・モデルに代わるメソッドです。トランザクションおよび並行処理の制御用の Native SDK モデルは ObjectScript メソッドに基づいており、.NET モデルと互換性はありません。トランザクションに Native SDK メソッド呼び出しが含まれる場合は、Native SDK モデルを使用する必要があります。
ObjectScript トランザクション・モデルの詳細は、"ObjectScript の使用法" の “トランザクション処理” を参照してください。
Native SDK for .NET には、トランザクションを制御するために以下のメソッドが用意されています。
-
IRIS.TCommit() — 1 レベルのトランザクションをコミットします。
-
IRIS.TStart() — トランザクションを開始します (このトランザクションは入れ子になっている場合あり)。
-
IRIS.GetTLevel() — 現在のトランザクション・レベルを示す int 値 (トランザクション内でない場合は 0) を返します。
-
IRIS..TRollback() — セッション内の開いているトランザクションすべてをロールバックします。
-
IRIS..TRollbackOne() — 現在のレベルのトランザクションのみをロールバックします。入れ子になったトランザクションである場合、それより上のレベルのトランザクションはロールバックされません。
以下の例では、3 レベルの入れ子のトランザクションを開始し、各トランザクション・レベルに異なるノードの値を設定します。3 つのノードはすべて出力され、それらに値があることが証明されます。その後、この例では、2 番目と 3 番目のレベルがロールバックされ、最初のレベルがコミットされます。3 つのノードはすべて再び出力され、依然として値があるのは最初のノードのみであることが証明されます。
String globalName = "myGlobal";
iris.TStart();
// GetTLevel() is 1: create myGlobal(1) = "firstValue"
iris.Set("firstValue", globalName, iris.GetTLevel());
iris.TStart();
// GetTLevel() is 2: create myGlobal(2) = "secondValue"
iris.Set("secondValue", globalName, iris.GetTLevel());
iris.TStart();
// GetTLevel() is 3: create myGlobal(3) = "thirdValue"
iris.Set("thirdValue", globalName, iris.GetTLevel());
Console.WriteLine("Node values before rollback and commit:");
for (int ii=1;ii<4;ii++) {
Console.Write(globalName + "(" + ii + ") = ");
if (iris.isDefined(globalName,ii) > 1) Console.WriteLine(iris.GetString(globalName,ii));
else Console.WriteLine("<valueless>");
}
// prints: Node values before rollback and commit:
// myGlobal(1) = firstValue
// myGlobal(2) = secondValue
// myGlobal(3) = thirdValue
iris.TRollbackOne();
iris.TRollbackOne(); // roll back 2 levels to GetTLevel 1
iris.TCommit(); // GetTLevel() after commit will be 0
Console.WriteLine("Node values after the transaction is committed:");
for (int ii=1;ii<4;ii++) {
System.out.print(globalName + "(" + ii + ") = ");
if (iris.isDefined(globalName,ii) > 1) Console.WriteLine(iris.GetString(globalName,ii));
else Console.WriteLine("<valueless>");
}
// prints: Node values after the transaction is committed:
// myGlobal(1) = firstValue
// myGlobal(2) = <valueless>
// myGlobal(3) = <valueless>
並行処理の制御
並行処理の制御は、InterSystems IRIS などのマルチプロセス・システムのきわめて重要な機能です。この機能により、データの特定の要素をロックして、複数のプロセスが同じ要素を同時に変更することによって起きるデータ破損を防ぐことができます。Native SDK トランザクション・モデルは、ObjectScript コマンドに対応する一連のロック・メソッドを提供します。これらのメソッドは、ADO.NET/SQL トランザクション・モデルで使用することはできません (詳細は、この章の冒頭にある警告を参照)。
クラス IRIS の以下のメソッドを使用して、ロックを取得および解放します。どちらのメソッドも、ロックが共有であるか排他であるかを指定する lockMode 引数を取ります。
Lock(string lockMode, int timeout, string globalName, Object[] subscripts)
Unlock(string lockMode, string globalName, Object[] subscripts)
-
IRIS.Lock() — lockMode、timeout、globalName、および subscripts 引数を取り、ノードをロックします。lockMode 引数は、前に保持されたロックを解放するかどうかを指定します。このメソッドは、ロックを取得できない場合、事前に定義した間隔が経過するとタイムアウトします。
-
IRIS.Unlock() — lockMode、globalName、および subscripts 引数を取り、ノードのロックを解放します。
以下の引数値を使用できます。
-
lockMode — 共有ロックを表す S という文字、エスカレート・ロックを表す E という文字、または共有およびエスカレート・ロックを表す SE という文字の組み合わせ。既定値は空の文字列 (排他の非エスカレート) です。
-
timeout — ロックの取得を試行するときに待機する秒数。
管理ポータルを使用して、ロックを検証できます。System Operation > Locks に移動して、システムでロックされている項目のリストを表示します。
現在保持されているロックをすべて解放するには、2 つの方法があります。
-
IRIS.ReleaseAllLocks() — この接続で現在保持されているロックをすべて解放します。
-
接続オブジェクトの Close() メソッドが呼び出されると、すべてのロックおよびその他の接続リソースが解放されます。
並行処理の制御に関する詳細な説明は、このドキュメントの対象ではありません。この内容に関する詳細は、以下のドキュメントと技術文書を参照してください。
-
"ObjectScript の使用法" の “トランザクション処理” および “ロック管理”
-
"サーバ側プログラミングの入門ガイド" の “ロックと並行処理の制御”
-
"ObjectScript リファレンス" の “LOCK”