クリック画像の実寸表示

段ボール箱を机にした猫 ファイルメーカー(filemaker)のちらしの裏のメモ書き

TOP  >  FileMakerでトランザクション処理を実行する
作成日:2025年02月03日

FileMakerでトランザクション処理を実行する

イメージイラスト
にゃん太

どうも、にゃん太です

かなり以前の話ですが、FileMaker 19.6.1でトランザクション処理が追加されました

規模が大きい開発では、この機能が使えるかは非常に重要です

今回のメモでは、今更ながらトランザクション処理について書いていきます


トランザクション処理とは

まずは、トランザクション処理について説明します
トランザクション(trasaction)とは、本来の意味としては「商取引」を指すビジネス用語です
そこから転じて、IT分野では処理の一貫性を保つために関連する複数の処理をまとめて実行する仕組みを「トランザクション処理」と呼ぶようになったそうです
データベース上で処理を行う場合、一連の処理として複数のテーブルに跨ってデータ処理を行う事は少なくありません
こうした処理は正しく完了すれば問題ありません
しかし、システム障害が発生して処理途中で強制終了されるなどした場合、一部のテーブルだけが変更された状態になる事があります
こうなるとデータの整合性が取れなくなり、運用上非常に問題になってしまいます
その対策としてトランザクション処理は存在しています
一連の動作が完了した際に変更が適用され、問題が生じた場合などには一連の処理全てが取り消されます
その結果、データの整合性を保った運用が可能となるのです

トランザクション処理の例

トランザクション処理の例としては、在庫の出荷などがあります
構造はシンプルに在庫テーブルと出荷テーブルを用意します
在庫から商品Aを30箱出荷する処理を行った場合、下記の様にテーブルが変更されます

在庫出荷時のテーブル変化
在庫テーブルから商品Aの在庫数が30減り、出荷テーブルで商品Aの出荷数30が新規登録されているのが分かります
本来ならあるべき他の要素を排除した、すごくシンプルな処理ですね
これを実行するスクリプトを書けば、以下の様になります

在庫出荷

# ################################################## # 在庫出荷スクリプト # ################################################## #商品と数量は引数で受け取る 変数を設定 [$param; 値: Get ( スクリプト引数 )] 変数を設定 [$商品; 値: JSONGetElement ( $param; "商品" )] 変数を設定 [$数量; 値: JSONGetElement ( $param; "数量" )] # 商品確認 レイアウト切り替え [「在庫テーブル」(在庫テーブル); アニメーション: なし] 検索モードに切り替え [一時停止: オフ] フィールド設定 [在庫テーブル::商品コード; "==" & $商品] エラー処理 [オン] 検索実行 [] エラー処理 [オフ] If [Get ( 対象レコード数 ) = 0] 現在のスクリプト終了 [テキスト結果: "商品登録なし"] End If # 在庫確認 If [在庫テーブル::在庫数 < $数量] 現在のスクリプト終了 [テキスト結果: "数量不足"] End If # 在庫数量の減算 フィールド設定 [在庫テーブル::在庫数; 在庫テーブル::在庫数 - $数量] # 出荷の登録 レイアウト切り替え [「出荷テーブル」(出荷テーブル); アニメーション: なし] 新規レコード/検索条件 フィールド設定 [出荷テーブル::出荷商品コード; $商品] フィールド設定 [出荷テーブル::出荷数量; $数量] 現在のスクリプト終了 [テキスト結果: "成功"]

処理エラー発生した場合の挙動

説明するまでも無いでしょうが、一応途中でエラー発生した場合の挙動も見てみましょう
スクリプトの27行目で在庫数量を減算し、33行目で出荷数量を登録しています
この間でシステムエラーなどで終了したとしましょう

在庫出荷

# ################################################## # 在庫出荷スクリプト # ################################################## # 商品と数量は引数で受け取る 変数を設定 [$param; 値: Get ( スクリプト引数 )] 変数を設定 [$商品; 値: JSONGetElement ( $param; "商品" )] 変数を設定 [$数量; 値: JSONGetElement ( $param; "数量" )] # 商品確認 レイアウト切り替え [「在庫テーブル」(在庫テーブル); アニメーション: なし] 検索モードに切り替え [一時停止: オフ] フィールド設定 [在庫テーブル::商品コード; "==" & $商品] エラー処理 [オン] 検索実行 [] エラー処理 [オフ] If [Get ( 対象レコード数 ) = 0] 現在のスクリプト終了 [テキスト結果: "商品登録なし"] End If # 在庫確認 If [在庫テーブル::在庫数 < $数量] 現在のスクリプト終了 [テキスト結果: "数量不足"] End If # 在庫数量の減算 フィールド設定 [在庫テーブル::在庫数; 在庫テーブル::在庫数 - $数量] # ここでエラー発生 現在のスクリプト終了 [テキスト結果: "システム障害発生!"] # 出荷の登録 レイアウト切り替え [「出荷テーブル」(出荷テーブル); アニメーション: なし] 新規レコード/検索条件 フィールド設定 [出荷テーブル::出荷商品コード; $商品] フィールド設定 [出荷テーブル::出荷数量; $数量] 現在のスクリプト終了 [テキスト結果: "成功"]

当然ですが、最後の出荷処理が登録されません
イメージとしては下図の通りです

在庫出荷時のテーブル変化(失敗時)
こうなると、在庫は減っているのに出荷はされないという事になってしまい、数字が合わなくなってしまいます

トランザクション処理

それでは、FileMakerにおけるトランザクション処理を見てみましょう
使い方は簡単で、トランザクション処理した内容を「トランザクションを開く[]」と「トランザクション確定」の間に挟むだけです
上記のスクリプトであれば、下記の様に書きます

在庫出荷

# ################################################## # 在庫出荷スクリプト # ################################################## # 商品と数量は引数で受け取る 変数を設定 [$param; 値: Get ( スクリプト引数 )] 変数を設定 [$商品; 値: JSONGetElement ( $param; "商品" )] 変数を設定 [$数量; 値: JSONGetElement ( $param; "数量" )] # 商品確認 レイアウト切り替え [「在庫テーブル」(在庫テーブル); アニメーション: なし] 検索モードに切り替え [一時停止: オフ] フィールド設定 [在庫テーブル::商品コード; "==" & $商品] エラー処理 [オン] 検索実行 [] エラー処理 [オフ] If [Get ( 対象レコード数 ) = 0] 現在のスクリプト終了 [テキスト結果: "商品登録なし"] End If # 在庫確認 If [在庫テーブル::在庫数 < $数量] 現在のスクリプト終了 [テキスト結果: "数量不足"] End If トランザクションを開く[] # 在庫数量の減算 フィールド設定 [在庫テーブル::在庫数; 在庫テーブル::在庫数 - $数量] # ここでエラー発生 現在のスクリプト終了 [テキスト結果: "システム障害発生!"] # 出荷の登録 レイアウト切り替え [「出荷テーブル」(出荷テーブル); アニメーション: なし] 新規レコード/検索条件 フィールド設定 [出荷テーブル::出荷商品コード; $商品] フィールド設定 [出荷テーブル::出荷数量; $数量] トランザクション確定 現在のスクリプト終了 [テキスト結果: "成功"]

このスクリプトを動かした動画がこちらです


トランザクション処理中に処理が終了されたら、データが元に戻されているのが分かります
この様に、データの整合性を保った処理ができる便利な機能です
機能追加も手軽ですので、積極的に使用していきたいですね!

メモ書き終了の案内イラスト

以上で今日のメモ書きは終了です

内容はいかがでしたか?

もしご意見やご要望、誤りの指摘などありましたら、下記フォームよりお気軽にご連絡ください

ご連絡フォーム