GeneXusの非同期処理について

先日「GeneXusで非同期処理は実装できるか?」と言うご質問を頂きましたので、本日は非同期処理の実装方法について書こうと思います。

非同期処理とは

実装方法の説明の前に、非同期処理とは何かについて説明します。

まず、非同期ではない処理(同期処理)とは下記のようなイメージです。

同期処理

計算処理を実行すると、プロシージャが呼ばれ処理が終了するまで下記のように待機となります。
待機中は他の画面へ遷移したり、別処理を実行したりすることはできません。


次は非同期処理のイメージです。

非同期処理

計算処理を実行するとプロシージャは呼ばれますが、プロシージャの処理終了を待ちません。

このように非同期処理は処理終了を待ちませんので、処理中も画面を切り替えたり、他の処理を行うことが出来ます。

ただ、処理の終了を判断できませんので、別途処理の終了を判断する画面を作る等の実装が必要となります。

非同期処理の実装方法

GeneXusで非同期処理を実装するには「Submit」と言うメソッドを使用します。

GeneXus Wiki
Submitメソッドについて

同期処理はプロシージャを「Call」や「Udp」で呼ぶのですが、非同期処理は「Submit」で呼びます。

一つ注意しなければ行けない点は、Submitの第二引数以降が、プロシージャの第一引数以降と一致します。
※Submitの第一引数はiSeries アプリケーション内でのみ使用され、他のすべてのジェネレーターでは無視されます。

これだけで非同期処理の実装は完了です。

非同期処理監視画面の作成

プログラムを非同期で動かすと、まだ処理しているのか終了しているのかが分かりません。

プログラムに開始ログと終了ログを出力するように記述すれば判断できますが、今回はデータベースに実行結果を持って確認してみます。

まずはテーブルを作成します。

※最低限の項目で簡易的に作成しました。
(バッチログNoはAutoNumberプロパティをTrue)


次にバッチログテーブルにデータを登録するプロシージャを作成します。

Rules

Source

今回こちらのバッチログを書き込むプロシージャは、トランザクション処理を分けるので「Execute in New LUW」のプロパティをTrueにしてください。
※Execute in New LUWプロパティについては下記の記事に記載しております。
トランザクション処理を分ける実装

また今回は簡易的なものなので、エラーハンドリングは省略しております。

バッチログ書き込み処理の実装

非同期で走らせる処理にバッチログ書き込みプロシージャを実装します。

InsBatchLogPへ渡すパラメータは下記のとおりです。
第1パラメータ:処理名
第2パラメータ:開始ログは0固定、終了ログは開始ログのバッチログNo
第3パラメータ:開始ログは採番されたバッチログNo、終了ログは0固定

今回時間がかかる処理は省略して、120秒待機するようにしました。
「開始ログ作成→120秒待機→終了ログ作成」と言う流れですね。

動作確認

実行画面から計算処理を実行します。

実行後、バッチログ監視画面へ遷移します。

計算処理が動いて、処理されてますね。
まだ処理中なので終了日時は入っていません。

ちょうど120秒後に終わって、終了日時が入りました。

これで終了が取れない非同期処理でも、終了したことが分かります。

まとめ

非同期処理は簡単に実装できますが、実行のログをどうやって取ろうかと考えたり、また非同期処理実行中に、同一処理を走らせた場合どうするかと仕様を考えるのが大変ですね。

今回は処理中に同一処理を走らせた場合の考慮はしませんでしたが、通常はバッチログに同一処理で終了日時が入っていないデータがあったら実行できない等の制御が必要になります。

非同期処理ができると並列処理なんかもできるので、バッチ処理の大幅な速度改善が可能だと思います。

良かったら実装してみてください。

以上です。

Blog一覧へ