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?

$SEQUENCE

複数のプロセスで共有されているグローバル変数をインクリメントします。

Synopsis

$SEQUENCE(gvar)
$SEQ(gvar)

SET $SEQUENCE(gvar)=value
SET $SEQ(gvar)=value

パラメータ

gvar

値がインクリメントされる変数。通常、gvar は、添え字付きあるいは添え字なしのグローバル変数 (^gvar) です。変数を定義する必要はありません。gvar が定義されていない場合、または NULL 文字列 ("") に設定されている場合、$SEQUENCE は、初期値 0 を持つものとしてそれを扱い、状況に応じてインクリメントし、値 1 を返します。

gvar に対してリテラル値を指定することはできません。単純なオブジェクト・プロパティ参照を gvar として指定することはできません。構文 obj.property を使用すると、多次元プロパティ参照を gvar として指定できます。

説明

$SEQUENCE は、同じグローバル変数について一意の (重複していない) 整数インデックスを複数のプロセスで素早く取得する手段を提供します。各プロセスについて、$SEQUENCE は整数値のシーケンス (範囲) を割り当てます。その後の $SEQUENCE の呼び出しにより、そのプロセスに対して割り当てられたシーケンス内の次の値にインクリメントします。割り当てられたシーケンス内のすべての正数値をプロセスが消費すると、新しい整数値のシーケンスが自動的に割り当てられます。$SEQUENCE は、割り当てる整数値のシーケンスのサイズを自動的に決定します。また、シーケンスの割り当てごとに、割り当てられるシーケンスのサイズを個別に決定します。このシーケンスは単一の整数になる場合もあります。

$SEQUENCE は、常に整数値を 1 だけインクリメントします。既定では、$SEQUENCE は正の整数 (1から開始) を割り当てます。ただし、$SEQUENCE は負の整数に設定することもできます。負の整数はゼロに向かってインクリメントされます。$SEQUENCE が負の整数に設定された場合、その後の呼び出しはインクリメントとしてゼロを割り当てる場合があります。gvar を整数以外の値に設定すると <ILLEGAL VALUE> エラーが生成されます。

$SEQUENCE は、複数のプロセスで同じグローバルを同時にインクリメントするときに使用されます。この処理は、$SEQUENCE でも $INCREMENT でも実行できますが、通常 $SEQUENCE の方がパフォーマンスにおいて優れています。$SEQUENCE がインデックスを割り当てる順序は、$INCREMENT の順序とは異なります。各プロセスに単一の整数インクリメントを割り当てる $INCREMENT の動作とは異なり、$SEQUENCE は、プロセスにインクリメントの連続的な範囲を割り当てることができます。これにより、プロセスの衝突と同期化を減らすことで、パフォーマンスを大幅に向上させることができます。連続的なレコード ID はプロセスごとにグループ化されるため、レコードの挿入時におけるデータ・ブロック・パフォーマンスも向上させることができます。

プロセスが $SEQUENCE を呼び出すと、以下のいずれかが発生します。

  • ^gvar グローバル変数を定義しているプロセスがないため、この変数は未定義になります。$SEQUENCE によって返される整数は 1 から開始されます。

  • ^gvar グローバル変数は、別のプロセスからの $SEQUENCE 呼び出しによって最後に変更されました。$SEQUENCE によって返された整数は、別のプロセスに割り当てられたシーケンスの後の最初の整数から開始されます。

  • ^gvar グローバル変数は、任意のプロセスから呼び出された SET $SEQUENCE によって最後に変更されました。$SEQUENCE によって返された整数は、$SEQUENCE が設定された値の後の最初の整数から開始されます。

$SEQUENCE がプロセスに割り当てるシーケンスのサイズは、内部のタイムスタンプにより左右されます。プロセスが 2 回目に $SEQUENCE を呼び出したときに、Caché は前のタイムスタンプを現在の時刻と比較します。これらの $SEQUENCE 呼び出し間の時間に応じて、Caché は単一のインクリメントまたは計算されたインクリメントのシーケンスのいずれかをプロセスに割り当てます。

  • 割り当てられたシーケンスが 1 の場合。$SEQUENCE は、$INCREMENT のように動作します。

  • 割り当てられたシーケンスが > 1 の場合。$SEQUENCE は、このプロセスごとのインクリメントのシーケンスを使用します。各プロセスがそれぞれの割り当てられたシーケンスを使用し、その後、新しいシーケンスが各プロセスに割り当てられます。

例えば、プロセス A とプロセス Bがどちらも同じグローバルをインクリメントします。各プロセスが最初にグローバルをインクリメントする際は、単一のインクリメントです。次に各プロセスがグローバルをインクリメントする際は、Caché が 2 つの $SEQUENCE 処理を比較して、インクリメントのシーケンスを計算します (このシーケンスは 1 つの整数になる場合があります)。その後の $SEQUENCE 処理は、これらのプロセスごとのシーケンスをすべて使用した後、インクリメントの再割り当てを行います。この結果、次のようなインクリメントになります。A1、B2 (クロックを設定する単一のインクリメント)、A3 (Cache が A1 と A3 を比較してプロセス A に 4、5、6、7 を割り当てる)、B8 (Cache が B2 と B8 を比較してプロセス B に 9、10、11 を割り当てる)。完全なインクリメントのシーケンスは、次のようになります。A1、B2、A3、A4、B8、A5、A6、B9、A7、B10、B11。

割り当てられたシーケンスの一部がプロセスで使用されない場合、残りの数はインクリメント・シーケンス内で未使用となります。

以下の例では、$SEQUENCE によって返されたインクリメント整数 (現在のシーケンス数) と gvar の値 (割り当てられたシーケンス数の最大値) 間の相違を示します。

  SET $SEQUENCE(^myseq)=""
  FOR i=1:1:15 {WRITE "increment:",$SEQ(^myseq)," allocated:",^myseq,! }

グローバル変数を用いた $SEQUENCE の使用に関する詳細は、"Caché グローバルの使用法" の "多次元ストレージの使用法 (グローバル)" を参照してください。

専用グローバル変数

$SEQUENCE(^gvar) の最初の呼び出しによってシーケンスが開始されると、そのシーケンスの有効範囲内における ^gvar 値への以降の変更は、$SEQUENCE(^gvar) の呼び出しによってのみ可能になります。その他の関数または文を使用して ^gvar の値を変更すると、シーケンスが未定義になります。

同じグローバルに対する $SEQUENCE および $INCREMENT の使用の制限事項について、以下に説明します。

SET $SEQUENCE

SET $SEQUENCE を使用することで、$SEQUENCE グローバルを削除したり、リセットしたりできます。SET $SEQUENCE は、グローバル変数をリセットして、他のプロセスに割り当てられた整数のシーケンスの割り当てを解除します。

  • SET $SEQUENCE(^gvar)="" は、指定されたグローバル・ノードを削除し、キャッシュされた $SEQUENCE 数を持つすべてのジョブを通知して、それらの現在のインクリメント値を消去します。$SEQUENCE の最初の呼び出しは 1 にインクリメントされます。SET $SEQUENCE(^gvar)="" は、指定されたグローバル・ノードのみを削除します。そのノードの下位ノード (存在する場合) は削除しません。

  • SET $SEQUENCE(^gvar)=n (n は整数) は、指定されたグローバル・ノードを n にリセットして、キャッシュされた $SEQUENCE 数を持つすべてのジョブを通知して、それらの現在のインクリメント値を消去します。すべてのジョブにおける以降の $SEQUENCE の呼び出しでは、新しいインクリメント開始値 n が使用されます。

    SET $SEQUENCE^gvar を小数値に設定しようとすると、<ILLEGAL VALUE> エラーが発生します。SET $SEQUENCE^gvar を数値以外の文字列に設定しようとすると、^gvar は 0 に設定されます。

KILL ^gvarSET ^gvar を使用して、$SEQUENCE グローバルの削除やリセットを行うことはできません。これらのコマンドは、プロセスに割り当てられた整数のシーケンスの割り当て解除を行わないためです。

パラメータ

gvar

インクリメントされる整数を含む変数。この変数を定義する必要はありません。$SEQUENCE の最初の呼び出しにより、未定義の変数が 0 として定義され、その値が 1 にインクリメントされます。gvar 値は、正または負の整数とする必要があります。

通常、gvar パラメータは、添え字付きあるいは添え字なしのグローバル変数 (^gvar) です。グローバル変数には、拡張グローバル参照を含めることができます。添え字付きグローバル変数の場合は、ネイキッド・グローバル参照を使用して指定できます。

gvar パラメータは、ローカル変数またはプロセス・プライベート・グローバルのいずれかになります。ただし、$SEQUENCE は複数のプロセスにわたる使用を意図したものであるため、ほとんどの場合、この使用は意味がありません。ローカル変数またはプロセス・プライベート・グローバルでの $SEQUENCE の使用は、1 の数値インクリメントでの $INCREMENT の使用と同義です。ロック、ジャーナリング、トランザクション・ロールバックに関する下記の $SEQUENCE に関する制限事項は、ローカル変数およびプロセス・プライベート・グローバルには適用されません。ローカル変数またはプロセス・プライベート・グローバルでの $SEQUENCE の使用では、$INCREMENT と同じエラーが発生します。これは、次のセクションに記載されているグローバル変数での $SEQUENCE のエラー動作とは異なります。

gvar パラメータは、多次元プロパティ参照でもかまいません。例えば、$SEQUENCE(..Count) のように指定します。非多次元オブジェクト・プロパティとすることはできません。非多次元オブジェクト・プロパティをインクリメントしようとすると、<OBJECT DISPATCH> エラーが発生します。

$SEQUENCE は、特殊変数をインクリメントできません。これは、SET を使用して変更できるものでも同じです。特殊変数をインクリメントしようとすると、<SYNTAX> エラーが発生します。

非常に大きな数値のインクリメント

$SEQUENCE によって返される整数は、-9223372036854775807 から 9223372036854775806 (-2**63+1 から 2**63-2) の範囲内にある数値です。この範囲外の整数を使用してグローバル変数での SET $SEQUENCE を試行すると、<ILLEGAL VALUE> エラーが生成されます。

以下の例では、グローバル変数での $SEQUENCE を 9.223372036854775800E18 に設定できますが、範囲制限を超えてこの数値をインクリメントすると <MAXINCREMENT> エラーが生成されます。この例を繰り返し実行することで、“低速インクリメント” と “高速インクリメント” を実行できます。この例の “高速インクリメント” では、$SEQUENCE が範囲の上限を超えて数のシーケンスを割り当てようとするため、実際に範囲の上限までインクリメントする前に <MAXINCREMENT> が出される場合があります。

  TRY {
  SET rand=$RANDOM(2)
  SET $SEQUENCE(^bignum)=9.223372036854775800E18
    IF rand=0 {  WRITE "slow increments:",!
    FOR x=1:1:10 {WRITE $SEQUENCE(^bignum)," increment #",x,!
                HANG .5 }
    }
    IF rand=1 {WRITE "fast increments:",!
    FOR i=1:1:10 {WRITE $SEQUENCE(^bignum)," increment #",i,!}
    }
  }
  CATCH exp { WRITE !,"In the CATCH block",!
                IF 1=exp.%IsA("%Exception.SystemException") {
                  WRITE "System exception",!
                  WRITE "Name: ",$ZCVT(exp.Name,"O","HTML"),!
                  WRITE "Location: ",exp.Location,!
                }
                ELSE { WRITE "unknown error",! }
  }

これらの種類のエラーは、グローバル変数をインクリメントする場合にのみ発生します。

$SEQUENCE または $INCREMENT

$SEQUENCE は、特に複数の同時プロセスが関わる整数インクリメント処理の用途で使用されます。$INCREMENT は、より汎用的なインクリメント/デクリメント関数です。

  • $SEQUENCE は、整数を 1 だけインクリメントします。$INCREMENT は、任意の数値を任意の指定値単位でインクリメントまたはデクリメントします。

  • $SEQUENCE は、プロセスにインクリメントのシーケンスを割り当てることができます。$INCREMENT は、1 つのインクリメントのみを割り当てます。

  • SET $SEQUENCE は、グローバルの変更または未定義化 (削除) の用途で使用できます。$INCREMENT は、SET コマンドの左側で使用することはできません。

Note:

$SEQUENCE および $INCREMENT は、ID アロケーションなどの、単純に数値をインクリメントする操作を実行するときにのみ、同じグローバル変数に使用できます。同じグローバルに対する $SEQUENCE および $INCREMENT のその他の用途は、予測できない結果になる可能性があるため、お勧めしません。

ロックと同時グローバル・インクリメント

$SEQUENCE は、$SEQUENCE 呼び出しとその他の $SEQUENCE 呼び出しとの同期のみを実施する、特殊な効率の良いロック手法を使用します。$SEQUENCE によって使用されるグローバルで LOCK コマンドを使用しても、$SEQUENCE には何も影響しません。例えば、プロセス 1 が ^COUNTER でロックを実行すると仮定します。

   LOCK ^COUNTER

次にプロセス 2 が ^COUNTER をインクリメントするとします。

   SET x=$SEQUENCE(^COUNTER)

プロセス 2 は、プロセス 1 によって保持されているロックによって、^COUNTER のインクリメントが妨げられることはありません。

$SEQUENCE とトランザクション処理

  • ロック : $SEQUENCE は通常、新しいエントリをデータベースに追加する前に、カウンタをインクリメントするために使用します。$SEQUENCE を使用すると、LOCK コマンドの使用をしなくても、この操作を迅速に行うことができます。このトレード・オフは、gvar がロックされていないということです。gvar は、トランザクション中の 1 プロセスによってインクリメントされます。トランザクションの処理中に、並列トランザクション中の別のプロセスによってでもインクリメントできます。

  • ロールバック : $SEQUENCE の呼び出しはジャーナルされません。したがって、トランザクションのロール・バックで gvar の値は変更されません。ロール・バックされたトランザクション中に $SEQUENCE によって割り当てられた整数値は、以降の $SEQUENCE の呼び出しによる割り当てで使用できません。

分散型データベース環境での $SEQUENCE の使用方法の詳細は、"Caché 分散データ管理ガイド" の “分散アプリケーションの開発” の章の "$INCREMENT 関数とアプリケーション・カウンタ" を参照してください。

関連項目

FeedbackOpens in a new tab