トランザクションとロック
このセクションで説明する項目は以下のとおりです。
-
トランザクションの制御 — トランザクションを処理するためのメソッドについて説明します。
-
ロックの取得および解放 — さまざまなロック・メソッドの使用法について説明します。
-
トランザクションでのロックの使用 — トランザクション内のロックの例を提供します。
トランザクションの制御
Native SDK には、トランザクションを制御するために以下のメソッドが用意されています。
-
Iris.tCommit() — 1 レベルのトランザクションをコミットします。
-
Iris.tStart() — トランザクションを開始します (このトランザクションは入れ子になっている場合あり)。
-
Iris.getotalevel() — 現在のトランザクション・レベル (トランザクション内でない場合は 0) を返します。
-
Iris..tRollback() — セッション内の開いているトランザクションすべてをロールバックします。
-
Iris..tRollbackOne() — 現在のレベルのトランザクションのみをロールバックします。入れ子になったトランザクションである場合、それより上のレベルのトランザクションはロールバックされません。
以下の例では、3 レベルの入れ子のトランザクションを開始し、各トランザクション・レベルに異なるノードの値を設定します。3 つのノードはすべて出力され、それらに値があることが証明されます。その後、この例では、2 番目と 3 番目のレベルがロールバックされ、最初のレベルがコミットされます。3 つのノードはすべて再び出力され、依然として値があるのは最初のノードのみであることが証明されます。
const node = 'myGlobal';
console.log('Set three values in three different transaction levels:');
for (let i=1; i<4; i++) {
irisjs.tStart();
let lvl = irisjs.getTLevel()
irisjs.set(('Value'+lvl), node, lvl);
let val = '<valueless>'
if (irisjs.isDefined(node,lvl)%10 > 0) val = irisjs.get(node,lvl);
console.log(' ' + node + '(' + i + ') = ' + val + ' (tLevel is ' + lvl + ')');
}
// Prints: Set three values in three different transaction levels:
// myGlobal(1) = Value1 (tLevel is 1)
// myGlobal(2) = Value2 (tLevel is 2)
// myGlobal(3) = Value3 (tLevel is 3)
console.log('Roll back two levels and commit the level 1 transaction:');
let act = [' tRollbackOne',' tRollbackOne',' tCommit'];
for (let i=3; i>0; i--) {
if (i>1) {irisjs.tRollbackOne();} else {irisjs.tCommit();}
let val = '<valueless>'
if (irisjs.isDefined(node,i)%10 > 0) val = irisjs.getString(node,i);
console.log(act[3-i]+' (tLevel='+irisjs.getTLevel()+'): '+node+'('+i+') = '+val);
}
// Prints: Roll back two levels and commit the level 1 transaction:
// tRollbackOne (tLevel=2): myGlobal(3) = <valueless>
// tRollbackOne (tLevel=1): myGlobal(2) = <valueless>
// tCommit (tLevel=0): myGlobal(1) = Value1
ロックの取得および解放
クラス Iris の以下のメソッドを使用して、ロックを取得および解放します。どちらのメソッドも、ロックが共有であるか排他であるかを指定する lockMode 引数を取ります。
-
Iris.lock() — lockMode、timeout、lockReference、および subscripts 引数を取り、ノードをロックします。lockMode 引数は、前に保持されたロックを解放するかどうかを指定します。このメソッドは、ロックを取得できない場合、事前に定義した間隔が経過するとタイムアウトします。
-
Iris.unlock() — lockMode、lockReference、および subscripts 引数を取り、ノードのロックを解放します。
以下の引数値を使用できます。
-
lockMode — 共有ロックを表す S という文字、エスカレート・ロックを表す E という文字、または共有およびエスカレート・ロックを表す SE という文字の組み合わせ。既定値は空の文字列 (排他の非エスカレート) です。
-
lockReference — 曲折アクセント記号 (^) で始まり、その後にグローバル名が続く文字列 (例えば、単なる myGlobal ではなく ^myGlobal)。ほとんどのメソッドで使用される globalName パラメータとは異なり、lockReference パラメータには先頭に曲折アクセント記号を付ける必要があります。globalName ではなく lockReference を使用するのは、lock() および unlock() のみです。
-
timeout — ロックの取得を待機する秒数。この秒数を経過するとタイムアウトになります。
管理ポータルを使用して、ロックを検証できます。System Operation > Locks に移動して、システムでロックされている項目のリストを表示します。
トランザクションでのロックの使用
このセクションでは、前に説明したメソッドを使用して、トランザクション内での増分ロックについて説明します (“トランザクションの制御” および “ロックの取得および解放” を参照してください)。管理ポータルを開き、System Operation > Locks.に移動することによって、システムのロックされた項目のリストを表示できます。以下のコードの alert() の呼び出しによって、実行が一時停止され、リストが変更されるたびにリストを調べることができます。
現在保持されているロックをすべて解放するには、2 つの方法があります。
-
Iris.releaseAllLocks() — この接続で現在保持されているロックをすべて解放します。
-
接続オブジェクトの close() メソッドが呼び出されると、すべてのロックおよびその他の接続リソースが解放されます。
以下の例に、さまざまなロック・メソッドおよび解放メソッドを示します。
irisjs.set('exclusive node','nodeOne');
irisjs.set('shared node','nodeTwo');
// unlike global names, lock references *must* start with circumflex
const nodeOneRef = '^nodeOne';
const nodeTwoRef = '^nodeTwo';
try {
irisjs.tStart();
irisjs.lock('E',10,nodeOneRef,''); // lock nodeOne exclusively
irisjs.lock('S',10,nodeTwoRef,''); // lock nodeTwo shared
console.log('Exclusive lock on nodeOne and shared lock on nodeTwo');
alert('Press return to release locks individually');
irisjs.unlock('D',nodeOneRef,''); // release nodeOne after transaction
irisjs.unlock('I',nodeTwoRef,''); // release nodeTwo immediately
alert('Press return to commit transaction');
irisjs.tCommit();
}
catch { console.log('error'); }
// lock nodeOne non-incremental, nodeTwo shared non-incremental
irisjs.lock('',10,nodeOneRef,'');
alert('Exclusive lock on nodeOne, return to lock nodeOne non-incrementally');
irisjs.lock('S',10,nodeTwoRef,'');
alert('Verify that only nodeTwo is now locked, then press return');
// lock nodeOne shared incremental, nodeTwo exclusive incremental
irisjs.lock('SE',10,nodeOneRef,'');
irisjs.lock('E',10,nodeTwoRef,'');
alert('Two locks are held (one with lock count 2), return to release both locks');
irisjs.releaseAllLocks();
alert('Verify both locks have been released, then press return');