10.3.2. LockManager
同時実行制御は
LockManagerクラスにより実装され、適切なデフォルト動作を提供しますが、必要であればこの動作をオーバーライドすることもできます。setlockメソッドは、同時実行制御に対する主なインターフェースとなっています。デフォルトでは、JBoss Transaction Service のランタイムシステムは、オブジェクト毎にmultiple reader, single writerポリシーに従うといった厳密な2相ロッキングを強制します。LockManager クラスは操作が読み込みロックあるいは書き込みロックのいずれが必要なのか推測できないため、プログラマがロック取得を制御します。しかし、ロック解除は通常システムが制御しており、プログラマは何もする必要がありません。
LockManager クラスは、オブジェクトへのロック設定あるいはロック解除に関するリクエストを管理します。しかし、StateManagerから取得しているため、継承した機能の一部に関する呼出しも制御することができます。例えば、書き込みロックを設定するリクエストが許可された場合、書き込みロックを設定するということは、呼出中のメソッドがオブジェクトの変更を行うであろうと推測できるため、LockManager は、modified メソッドを直接呼び出します。オブジェクトが回復可能であれば、こうすることでリカバリ情報が保存されます。ロックを問題なく取得すると、activateの呼出しがトリガーされます。
そのため、
LockManager は永続オブジェクトのアクティベートおよび解除を行い、同時実行制御の管理に利用するResources を登録します。また、StateManager クラスを駆動することで、永続および回復可能なステートを操作し、オブジェクトのリカバリを行えるようにResources を登録します。自身で行う操作は、適切なロックを設定し、トランザクションを開始・終了し、StateManager クラスのsave_state と restore_stateメソッドを継承するのみです。
例10.9 LockResult の例
必要なロックタイプと再試行の回数をパラメータとして
setlock に渡し、ロックを取得する必要があります。タイプは、READ あるいは WRITEになっています。ロックの矛盾が起こると、以下のシナリオの1つのようになります。
- 再試行の値が
READorWRITEと同じ場合、setlockメソッドを呼び出したスレッドはロックが解除されるか、指定した合計タイムアウトを過ぎるまでブロックされます。タイムアウトになると、REFUSEDの値が返されます。 - ロックを最初に取得できない場合、
LockManagerが指定された回数を再試行し、試行に失敗してから次に失敗するまで指定のタイムアウト値の期間待機します。デフォルトの試行回数は100で、各試行の間隔は0.25秒となっています。
ロックに矛盾が発生すると、ロックのリクエストはタイムアウトしデッドロックが起こらないようにします。完全なデッドロック検出スキームが提供されています。リクエストされたロックを取得した場合、
setlock メソッドは、GRANTEDの値を返しますが、取得しなかった場合はREFUSEDの値を返します。ロックリクエストが許可された場合にのみ、操作に対するコードの残りが実行されるようにする必要があります。実用例については、例10.10「setlock の例」を参照してください。
例10.10 setlock の例
同時実行制御のメカニズムをアトミックアクションのメカニズムへ統合することで、オブジェクトへのロックが許可され、適切な情報が現在動作中のアトミックアクションに登録されるようにします。こうすることで、ロックを正しいタイミングで解除し、アトミックアクション内で取得したロックを明示的に解除する必要性をなくします。ただし、アトミックアクションの範囲外でオブジェクトへのロックを取得した場合、
releaselockメソッドを使いロックを解除する必要があります。