レコードロックを意識した開発 関連レコードのロック

前回は、レコードロックについて解説し、「レコードを開く」スクリプトステップを利用した開発例を紹介しました。今回は、レイアウトのコンテキストテーブルではなく、関連レコードのロックに焦点を当て解説してみようと思います。

関連レコードのロック

前回のブログでは、フィールドがアクティブで編集中の場合にレコードが開かれ、レコードロックが発生すると説明しました。レイアウト上にコンテキストテーブルのフィールドのみが配置されている場合、そのレコードのみがロックされます。
レイアウト上に関連レコードのフィールドやポータルが配置されている場合に、ロックされる対象のレコードの違いを確認してみたいと思います。

親、子テーブルを作り、以下 TOG を作成します。

親テーブルをコンテキストとしたレイアウトに、子テーブルを関連レコードとするポータルを配置します。

このポータルの1行を編集開始すると、子テーブルの1つのレコードを開いた状態にするだけでなく、コンテキストテーブルである親レコードも開かれます。
これにより、自分がポータルの1つの行を編集開始したとき、別のクライアントが同じ親レコードのポータル行を編集開始しようとしても、コンテキストテーブルのレコードが開いているためロック状態になり編集ができない、という動きになります。

スクリプトでレコードロックを確認する

スクリプト処理中にレコードロックが発生し、編集できていないのにエラーに気づかず、あたかも正常終了している、といった動きになっていてはいけません。

「レコードを開く」スクリプトステップを利用することで、レコードロックの状態を確認することができます。直後のステップで Get(最終エラー) を取得し、最終エラーが 0 ならレコードロックされておらず、301 の場合はレコードロックされているということが分かります。このステップは、ポータルの行に対しても利用できます。

変数を設定 [ $関連レコード数 ; 値: Count ( 子::主キー ) ] 
変数を設定 [ $n ; 値: 1 ] 
Loop [ フラッシュ: 常に ]
	Exit Loop If [ $n > $関連レコード数 ] 
	ポータル内の行へ移動 [ 選択: オフ ; ダイアログあり: オン ; $n ]
       レコード/検索条件を開く
	If [ Get ( 最終エラー ) <> 0 ] 
          //レコードロックにより編集できない場合301エラー
		レコード/検索条件復帰 [ ダイアログあり: オフ ]
		現在のスクリプト終了 [ テキスト結果:    ] 
	End If
	フィールド設定 [ 子::テキスト ; "テストテキスト" ] 

	変数を設定 [ $n ; 値: $n +1 ] 
End Loop

現在のスクリプト終了 [ テキスト結果:    ] 

ただし、レコードロックの判定を毎回行うと記述量が増えるので、なるべく楽をしたいところです。
レコードやポータル行ごとに、一番最初のフィールド設定の Get(最終エラー) を確認することで、レコードロックのエラーも同時に確認することができます。

変数を設定 [ $関連レコード数 ; 値: Count ( 子::主キー ) ] 
変数を設定 [ $n ; 値: 1 ] 
Loop [ フラッシュ: 常に ]
	Exit Loop If [ $n > $関連レコード数 ] 
	ポータル内の行へ移動 [ 選択: オフ ; ダイアログあり: オン ; $n ]
	フィールド設定 [ 子::テキスト ; "テストテキスト" ] 
	If [ Get ( 最終エラー ) <> 0 ]
          //レコードロックにより編集できない場合301エラー 
		レコード/検索条件復帰 [ ダイアログあり: オフ ]
		現在のスクリプト終了 [ テキスト結果:    ] 
	End If
	
	変数を設定 [ $n ; 値: $n +1 ] 
End Loop

現在のスクリプト終了 [ テキスト結果:    ] 

まとめ

実際の開発では、様々なTOを利用してスクリプト処理を行うことが一般的です。また、サーバー上のスクリプト実行やバッチ処理なども裏側で動作していることがあります。そのため、常にレコードロックによるエラーに注意を払いながら開発を行うことが重要です。
今回紹介した「レコードを初めて編集するときにエラーを確認する」方法は、レコードロックを確認するために必ず取り入れておきたい処理です。今後の開発に役立てていただければ幸いです。