互換性設定とパフォーマンス向上のための「隠し」機能についての継続的なシリーズを歓迎します。 最初の投稿では、QUERY BY FORMULA コマンドと、それがアプリケーションの動作に与える影響について見てきました。第2回目は「ピリオドとカンマをプレースホルダーとして使用する」という互換性オプションについて、「数字が>>>>>>>のように表示される」 問題を回避するために紹介しました。
3回目の今回は、「ネストされたトランザクション」について説明します。
もし、このオプションが互換性ページに表示されていない場合(4D v11以降で構造を作成したため)、またはすでに有効になっている場合は、これ以上読む必要はないでしょう。もし、そうでなければ、あなたのアプリケーションは、4D v2004 をエミュレートするモードで動作しています。あなたは、多くの素晴らしい機能を逃しているだけでなく、このモードはもはや4Dによってテストされていないため、危険な状態になっているのです。
25年前に4Dが初めてトランザクションを導入したとき、それは単一のトランザクションレベルしかサポートしていませんでした:操作はトランザクションの中にあるかないかのどちらかでした。しかし、4Dは10年以上前からマルチレベルの(ネストされた)トランザクションをサポートしています。ぜひ活用してください。
もし、トランザクションを使ったことがなければ、トランザクションに関するこのブログ記事を読むことをお勧めします。
ネストされたトランザクションの互換性フラグ
では、なぜこのようなオプションがあるのでしょうか?常にネストされたトランザクションを使用する方が良いのではないでしょうか?
はい、その方がずっといいです。しかし、既存のコードはシングルレベルトランザクションのみで書かれている可能性があり、そのためにオプションがあるのです。
START TRANSACTION
START TRANSACTION // second call by accident, ignored from 4D v2004
VALIDATE TRANSACTION // v2004 was now at the end, no transaction running anymore
// v11 still has a transaction open…
なぜですか?何が起こるのでしょうか?よくぞ聞いてくれました!エンドユーザーがシングルレベルのトランザクションしかないアプリケーションを終了させたとしよう。そのアプリケーションには、まだ未確認の、検証されていないトランザクションが開いているかもしれない。それらは自動的にキャンセルされ、すべての作業が失われる可能性があります!
ネストされたトランザクションの互換性フラグを有効にする前に、コードを慎重にレビューし、トランザクションへのすべての呼び出しがバランスされていることを確認する必要があります。オープンだけでなくクローズも確認してください。たとえば、IF条件の内部で呼び出されたメソッドはトランザクションを開始する可能性がありますが、コードが十分に構造化され整理されていない場合、見つけるのが困難な場合があります。
これを確認する方法は2つある。
- 1つは、完全なコード監査を行うことで、これは非常に時間がかかる。しかし、もう1つの方法があります。
- もし、あなたのアプリケーションが1つのプロセスしか使っていないなら、それはとても簡単なことかもしれません。On Exit イベントで、まだ開いているトランザクションがあるかどうか確認してください。もしそうなら、それを報告し(自分自身にメールを送る、管理者に電話するなど)、トランザクションを検証してください(それが偶然に開かれたトランザクションであると仮定して)。
プロセス数が増えるので、それらを識別する必要があります。どのプロセスでも、開始時や終了時に呼び出す汎用的なメソッドがあれば心配はない。そうでない場合は、これらのプロセスを見つけ、それぞれを変更する必要があります。各プロセスの終了時に Transaction level.
この時点では、他のことは何もしないでください。ネストされたトランザクションを使い始める前に、コードをチェックしてください。
トランザクションの一時停止
ネストされたトランザクションを有効にするとすぐに、別の利点に気がつくでしょう。スヌーズボタンを押すことができるのです!
例えば、あるトランザクションの中で、別のテーブルに保存されているカウンターを増やす必要があるとします(例: 請求書番号)。トランザクションが開いている限り、変更されたレコードはすべてロックされ、他のユーザーやプロセスが変更できないようにします。これは、請求書自体には良いことかもしれませんが、請求書番号カウンタにはあまり良いことではありません。これまで開発者は、この問題を回避するために、別のプロセスを開始し、通信を処理するためのプロセスを作成することを試みてきました。これは、トランザクションの外で何かを実行するためだけに、多くのコードを必要とします。幸いなことに、もっと良い方法があります。ネストされたトランザクションが有効になるとすぐに、いつでもそれを一時停止 することができるのです。これにより、カウンターをインクリメントし、トランザクションを再開することができます。
これはとても素晴らしい機能で、ドキュメントにそれについての記事があるほどです。
メモリ
ネストされたトランザクションを使うかどうかにかかわらず、 トランザクションは 、変更されたデータを一時的なバッファに格納するため、 必要なメモリを増加さ せることを認識する必要があります。それだけでなく、内部的に4Dはクエリを実行するための一時的なインデックスを構築しています。
その結果、テーブルが大きくなればなるほど(より多くのフィールドにインデックスが作成され、より多くのレコードが変更されるため)、より多くのメモリが必要となります。メモリ不足の場合、.4DDファイルの横にテンポラリファイルが作成されます(テンポラリバッファを保存するため)。これらのファイルは、メモリ不足を解消する一方で、アプリケーションのパフォーマンスを低下させる可能性があります。
つまり、トランザクションは素晴らしいものですが、1つのトランザクションの中で何百万ものレコードを操作するのは最善の策ではありません。