作成日:2025年03月03日
レコードの排他制御を考える


どうも、にゃん太です
FileMakerで業務アプリを作成する場合、FileMakerServerでの運用が基本になるかとおもいます
そうなると、同一レコードへの同時アクセスについて考える必要があります
今回のメモでは、レコードの排他制御について書いていきます
レコードの直接編集
FileMakerでアプリを作成する場合、レコードを編集する機能は概ね必須となります
レイアウトに編集させたいフィールドを配置し、そこでユーザーに入力をさせるというのが基本的な作り方です
例えば、次の画像の様なイメージですね
簡単な入力フォーム

ここに入力した後、全てのフィールドからフォーカスが外れると、入力内容はレコードに登録されます
入力中はレコードは自動的にロックされ、別のユーザーが同一レコードを編集しようとした場合には警告が表示されます
編集不可メッセージ

こうした挙動により、設計者は特に意識しなくても同時編集による問題は回避されます
ただし、編集中ユーザーがレコードロック中に離席するなどした場合、長時間に渡って編集できなくなってしまう場合があります
データの種類によってはそうした状態が問題となる場合があり、その場合は別の編集方法を考える必要に迫られます
グローバルフィールドによる間接編集
レコード編集中のロックを回避したい場合、グローバルフィールドを使用する方法があります
編集したいレコードの内容を一旦すべてグローバルフィールドに複製し、グローバルフィールドを編集します
編集が完了したら保存ボタンを押すなどの操作を経て、元のレコードに編集内容を上書きする、といった方法です
この方法なら、レコードロックは上書きしているごく短時間で済むので、他の方の操作を妨げません
とはいえ、この方法も問題があります
AさんとBさんが同時に編集画面を開き、Aさんが氏名を編集して保存した後、Bさんが住所を編集して保存した場合、Bさんの保存処理によって氏名が元の内容に上書きされてしまいます
これはあまり好ましくない動きです
対策としては2つ考えられます
まず1つ目は、呼び出し時点の情報を記録しておき、変更していないフィールドは上書きしない、という方法です
これはこれで別の問題がありそうですが、それぞれの編集内容は保存されます
2つ目の方法としては、修正回数を取得しておき、それが変わっていたら保存させない、という方法です
「Get (レコード編集回数)」によってレコードの編集回数が取得できますので、保存時にその数字が変わっていたら保存処理を停止させることができます
保存しようと思ったら入力内容を破棄させられるとなるとUX的にどうよ、という問題はありますが、意図しない結果になることはなくなります
スクリプトによるレコードの一括編集
スクリプト処理によって、複数のレコードを編集する場合があります
例えば請求書の一括作成を行い、請求書を作成したレコードには出力済みフラグを立てるといった処理です
こうした処理を行った場合、処理対象となるレコードが多ければ多いほど、どれかが編集中であるリスクは高くなります
そうした場合、特に対策を講じていなければ編集中レコードにフラグは立たないまま処理が進むことになり、後々問題が発生することになります
別テーブルでフラグ管理を行ったり、フラグが立たないデータが発生した場合には出力を停止してエラー表示される、などと言った対策をしておく必要があるでしょう
例えば、以下の様なスクリプトを組めば、全置換に失敗した段階で処理を中止することができます
スクリプト
# ################################################## # 処理中データがあったら処理中止 # ################################################## トランザクションを開く [] 変数を設定 [$savePath; 値: Get ( テンポラリパス ) & "filename.pdf"] フィールド内容の全置換 [ダイアログあり:オフ; input::フラグ; 1] レコードをPDFとして保存 [ダイアログあり:オフ; 「$savePath」; 対象レコード; フォルダを作成:オン] トランザクション確定 If [Get ( 最終エラー )] # エラー時の処理を実行する End If

以上で今日のメモ書きは終了です
内容はいかがでしたか?
もしご意見やご要望、誤りの指摘などありましたら、下記フォームよりお気軽にご連絡ください