LKE の演習

Mロックを使用する時は、より良く設計されていて定義されているロックプロトコルを使用する必要があります。ロックプロトコルでは、、ロックを取得し、タイムアウトを選択して使用し、Mロックを解放し、与えられた状況に従ってロック計画を定義し、潜在的なデッドロックの状況を識別し、デッドロックを避けるべきかまたは回復すできかの手段を提供などのために、ガイドラインを設定する必要があります。このセクションでは、2つの演習が含まれています。1番目の演習では、以前にこの章で説明したGT.Mロックの概念を補強します。2番目の演習は、デッドロックの状況を解説し、デッドロックを識別して解決するためにLKEが使用できる1つの方法を示します。

演習1:Mロックを使用して同時更新を防止

二人のユーザ(ジョンさんとトムさん)が、排他的にグローバル変数^ABCを更新する必要がある時の状況を考えてみます。

[注意] 注意

トランザクション処理は、潜在的な更新の競合(コンフリクト)の問題に対して、より効率的で、そして、より簡単に管理できるソリューションを提供します。詳細については、GT.MプログラマーズガイドMの一般的な言語機能 の章を参照してください。

ジョンさんがGT.Mプロンプトで、次のコマンドを実行します。

GTM>lock +^ABC

このコマンドは、"^ABC "上にGT.Mロックをかけます(グローバル変数^ABCでは無い)。注:+/- の無いロックは、常にプロセスによって保持されているすべてのロックを解放します。これらは暗黙的にデッドロックを回避します。 LOCK +のプロトコルは(デッドロックを避けるために)同じ順序でロックを蓄積する必要があります。

その後、ロックデータベースの状態を表示するには、次のコマンドを実行します。

GTM>zsystem "lke show -all"

このコマンドは、以下の出力を生成します:

DEFAULT ^ABC Owned by PID= 3657 which is an existing
process

今、^ABCのロックを解放せずに、トムさんのGT.Mプロンプトで次のコマンドを実行します。

GTM>lock +^ABC

このコマンドは、解放されるまで "^ABC " のリソース上のロックを待ちます。LOCKコマンドは、多少なりともグローバル変数^ABC をブロックしないことに注意して下さい。このコマンドは、LOCKデータベースに"^ABC"のリソースをロックするための要求を待ち行列(キュー)に格納します。たとえグローバル変数^ABC がジョンさんによってロックされていたとしても、その値をそれでも変更できることに注意してください。

今、ジョンさんのGT.Mプロンプトで、次のコマンドを実行します。

GTM>zsystem "LKE -show -all -wait"

このコマンドは、以下の出力を生成します:

DEFAULT ^ABC Owned by PID= 3657 which is an existing process 
Request PID= 3685 which is an existing process

この出力では、PID 3657でジョンさんに属するプロセスが、現在、グローバル変数^ABC のロックを所有していることと、そして、トムさんのPIDがそのロックの所有権を要求していること、を示しています。あなたが同時アクセスのプロトコルに従ってアプリケーションロジックを作成するには、このメカニズムを使用することができます。

演習2:デッドロックの状況を修正

これらユーザ(ジョンさんとトムさん)の両方が2つのテキストファイルを更新する必要がある時には、今、別の状況を考えてみましょう。更新が進行中に、GT.MのLOCKは、他のユーザがそのファイルをロックすることを防ぐ必要があります。いくつかのケースでは、新たな追加のロックを追加する前に、それらがそれら現在のロックを解放しないので、両方のユーザとも次に進むことができない、デッドロックが発生します。

デッドロックの状況は、次のような状況で発生する可能性があります。

John           Tom 
LOCK +file_1   LOCK +file_2 
LOCK +file_2   LOCK +file_1

ここでは、両方のユーザがデッドロックされており、どちらも次に進むことができません。デッドロックの状況が実際には基になるリソースをブロックしないことに注意してください。

今このような状況を作ってみましょう。

ジョンさんがGT.Mプロンプトで、次のコマンドを実行します。

GTM>set file1="file_1.txt"
GTM>lock +file1
GTM>open file1:APPEND 
GTM>use file1 
GTM>write "John",!
GTM>close file1

ジョンさんは、リソース "file1" のロックをリリースしていないことに注意してください。

トムさんのGT.Mプロンプトで、次のコマンドを実行します。

GTM> set file2="file_2.txt" 
GTM> lock +file2
GTM> open file2:APPEND 
GTM> use file2 
GTM>write "Tom",!
GTM>close file2

トムさんは、リソース"file2" のロックをリリースしていないことに注意してください。

今、ジョンさんのGT.Mプロンプトで、次のコマンドを実行します。

GTM>set file2="file_2.txt" 
GTM>lock +file2

後者のコマンドは、既にトムさんによってロックされている file2のリソース上でロックしようと試みます。したがって、この結果は、デッドロックの状況です。トムさんのために同じプロセスを繰り返し、リソースfile1をロックしようとします。

このデッドロック状態を表示するには、LKEプロンプトで次のコマンドを実行します。

LKE>show -all -wait 
file1 Owned by PID= 2080 which is an existing process 
Request PID= 2089 which is an existing process 
file2 Owned by PID= 2089 which is an existing process 
Request PID=2080 which is an existing process

ロックを解放するために他のユーザは待っているので、どちらのユーザも次に進むことができないというデッドロックの状況を示しています。あなたは、 LKE CLEAR -PID コマンドを使用して、ロックをクリアすることによって、この状況を解決することができます。

注意 注意

アプリケーションが予期しない動作につながる可能性があるので、本番(プロダクション)環境でデッドロックをクリアするために LKE CLEAR コマンドの使用は避けてください。本番(プロダクション)環境でデッドロックの状況をクリアするために、常に MUPIP STOP コマンドを使用してください。しかし、デバッグ環境では、ロックをデバッグしたり、ロックデータベースの状態を分析したり、 LKE CLEARで実験にでも使ったりできます。

inserted by FC2 system