【GxTips】For Each等におけるトランザクションの指定

【GxTips】For Each等におけるトランザクションの指定

お久しぶりです、全然(blog)書かないkudoです。

本日は案件内で便利さを実感したFor Eachでのトランザクション指定DataProviderでのFrom句についてご紹介します。

この機能、実はEv3から追加された機能で便利そうだとは思っていたのですが・・・
今まで携わっていた案件がEv2どまりだったため使う機会がありませんでした。

しかし、直近の案件でGx15を使う事となり改めてこの機能の便利さを実感できたのでご紹介します。

 

まず、For Each等とタイトルに記載しているのは

For EachとDataProviderで記述方法が異なるためです

For Eachの場合は

DataProviderの場合は

という書き方になります

For Eachのコードをみて気になった方もいるかと思いますが
Ev2までは

とFor Eachの後に項目属性を記述することで、Order句無しでソートが実行される仕様でしたが
Ev3からはトランザクションの指定が増えたことに伴い、ソートする場合はOrder節が必須となっています。

しかし、トランザクションの指定はこのような些細な変化を帳消しにするような利点を持っています。

 

GeneXusは推論エンジンを利用し、SQLを自動生成するという特性上
トランザクションの作り方によってはFor Eachをネストした場合に望んだテーブルを参照できない場合が発生します。

その場合、DefinedByOrderUniqueを利用し調整しますが
稀にそれだけでは望むテーブルが参照されず、泣く泣くサブルーチン別オブジェクトに変更し、実装していました。

しかし、トランザクションを指定できるようになったことで
DefinedByOrderUniqueより強力にトランザクションを指定できるようになり
今までサブルーチンなどで記載していたところをネストした形で記述できるようになりました。

以降、どのように変わるのかFor Eachを例にご紹介します。

 

Ev2までの記述

Ev3からの記述

トランザクションを指定する方法をとると、ソースコードを減らせるだけでなく
項目ごとの関連も見やすくなります。

また、あくまで体感の話になりますが
後者の書き方をした方がレスポンスが早く感じたため
おそらくSQLも1つに纏められているのだと思われます。(検証不足で申し訳ありません)

さらに副次的な効果としてビルド時間の短縮があります。
これは、For Eachごとにベースとなるトランザクションを指定するため、通常行われるFor Each内の項目属性からのベーステーブルを推論する処理が大幅に軽減され
その結果、ジェネレートにかかる時間が短くなり発生する効果です。

 

しかし、Ev3からの割と新しい変化だったためか、この便利な仕様を利用している案件が少ないように感じます。

ビルド時間やレスポンスに苦労している人は一度トランザクションの指定で改善できないか試してみてはいかがでしょうか?