バッチ再試行の有効化
財務と運用バッチに再試行メカニズムを実装することは、堅牢なデータ処理を維持するために不可欠です。 再試行メカニズムでは、エラーを自動的に処理することでエラー許容誤差を提供します。 そのため、手動での確認を必要とせずに、動作を変更せずに作業を変更することが保証されます。 また、不完全なトランザクションや失敗したトランザクションを再処理することで、データの整合性を強化します。 したがって、データが失われるリスクを減らします。 再試行のメカニズムは、ダウンタイムと手動介入を最小限に抑えることで、運用効率を向上させ、断続的なエラーや中断にもかかわらず、バッチ処理をスムーズに進めることができます。
バッチ タスクの再試行メカニズム
バッチ タスクには、次の 2 種類の再試行を使用できます:
- エラーの再試行またはバッチ サーバーの再起動を再試行 - このタイプの再試行を構成するには、バッチ ジョブ ページでバッチ タスクの再試行カウントを調整します。
- SQL の接続エラーの再試行 - バッチ クラスに BatchRetryable インターフェイスを実装するか、BatchInfo を使用してバッチクラスの Idempotent 属性を設定することで、このタイプの再試行をコードで実現できます。
エラーまたはバッチ サーバーの再起動を再試行する
この機能は、バッチ ジョブの設定で、バッチ タスクの再試行回数を調整することで構成できます。 最大再試行パラメータ は、エラー タイプまたはバッチ サーバーの再起動に関係なく、タスクの再試行の回数を決定します。 タスクが失敗した場合、バッチ プラット フォームは実行された再試行の回数を評価します。 カウントが 最大再試行回数 の値より小さい場合、タスクは再処理可能な状態にリセットされます。 最大試行回数パラメーターの最大許容値は 5 です。
バッチ ユーザー インターフェイスを介して 最大再試行回数 の値を設定するには、次の手順に従います。
- バッチ ジョブ ページでバッチ タスクの表示を選択します。
- 全般 タブで、バッチタスクの 最大試行回数フィールドの値を調整します。
注記
ランタイム バッチ タスクの再試行カウントの設定はサポートされていません。 この値をプログラムで定義しようとすると、プラットフォームはこの値を 0 (ゼロ) に上書きし、ランタイム タスクは再試行されません。
バッチ タスクが動的に生成される場合 (たとえば、ジョブがランタイム ジョブの場合)、BatchInfo クラスまたは BatchHeader クラスを使用して、プログラムで 最大再試行回数 値を構成できます。 次に例を示します。
class SampleBatchClass extends RunBaseBatch
{
void scheduleMyBatchClass()
{
BatchInfo info = this.batchInfo();
info.parmRetriesOnFailure(5);
...
}
...
}
class SampleBatchClass extends RunBaseBatch
{
void scheduleMyBatchClass()
{
BatchInfo info = this.batchInfo();
BatchHeader header = batchInfo.parmBatchHeader();
header.parmRetriesOnFailure(5);
...
}
}
BatchHeader を使用して設定された最大試行数値は、BatchInfo を使用してバッチタスクに設定された値を上書きします。 最大再試行回数 パラメーター が 0 (ゼロ) に設定されている場合、バッチ タスクは再試行されません。
SQL 一時接続エラーの再試行
現在、財務と運用アプリにおける Microsoft SQL Server への接続が簡単に失われると、すべてのバッチ タスクが失敗します。 この動作により業務プロセスが中断します。 クラウド サービスでは接続が失われることは避けられないので、Microsoft はこのタイプのエラーが発生した場合の自動再試行を有効にします。
注記
実行タスクは再試行可能またはべき等として指定できます。 SQL 接続接続エラーが発生した場合、プラットフォームはそれらを自動的に再試行します。
バッチ クラスが SQL の一時的な接続エラーに対して再試行可能であることを示すには、3 つの方法があります:
バッチ クラスに BatchRetryable インターフェイスを実装します。 BatchRetryable インターフェイスは 、ブール値を返す単一のメソッド isRetryable を持っています。 値が True の場合、バッチ クラスは再試行できます。 値が False の場合、バッチ クラスは再試行できません。 BatchRetryable インターフェイスは 、バージョン 10.0.18 で利用可能です (プラットフォーム更新プログラム 40 を使用)。 次の例では、バッチ クラスに対して IsRetryable を設定する方法を示します。
//RunBaseBatch class SampleBatchClass extends RunBaseBatch implements BatchRetryable { [Wrappable(true), Replaceable(true)] // Change to meet your customizability requirements public boolean isRetryable() // Use final if you want to prevent overriding { return true; // You can also use false if you do not want to enforce retryable behavior using isRetryable } ... }
//SysOperationServiceController class SampleBatchClass extends SysOperationServiceController implements BatchRetryable { [Wrappable(true), Replaceable(true)] // Change to meet your customizability requirements public boolean isRetryable() // Use final if you want to prevent overriding { return true; // You can also use false if you do not want to enforce retryable behavior using isRetryable } }
バッチ ユーザー インターフェイスで isRetryable の上書きを設定します。 システム管理>設定>バッチ クラス構成の上書きを開き、バッチ クラスを追加して、Is Retryable に必要な値を設定します。 ここに入力した値は、前のオプションのコードで指定された値より優先されます。
バッチ クラスのコードに isIdempotent フラグを設定します。 次の例は、バッチ クラスに Idempotent 属性を設定する方法を示しています。 Idempotentの既定値は False です。
//RunBaseBatch class SampleBatchClass extends RunBaseBatch { public void run() { this.batchInfo().parmIdempotent(true); // You can also use false if you do not want to enforce retryable behavior using Idempotent ..... } ... }
//SysOperationServiceController class SampleBatchClass extends SysOperationServiceController { public static SampleBatchClass construct(Args _args) { SampleBatchClass controller = new SampleBatchClass(); controller.batchInfo().parmIdempotent(true); // You can also use false if you do not want to enforce retryable behavior using Idempotent .... return controller; } ... }
バッチ クラスが "Retryable または Idempotent としてマークされている場合は、SQL の接続に失敗した場合に再試行されます。 この再試行は、バッチ タスクに対するバッチ再試行カウントとは関係なしです。
バッチ プラットフォームは、SQL 一時接続エラーの最大再試行回数と再試行間隔を管理します。 最初は、再試行は 5 秒後に開始され、間隔が 5 分に達すると終了します。 間隔の時間は、再試行の間隔ごとに指数関数的に増加します。 1 回目の再試行は 5 秒、2 回目は 8 秒、3 回目は 16 秒、4 回目は 32 秒です。
注記
SQL の一時的なエラーの場合、バッチ・プラットフォームは、対応するバッチ・クラスからスローされた例外が TransientSqlConnectionError タイプの例外である場合、または TransientSqlConnectionError タイプの例外をカスタム例外の中にネストされた例外としてラップしてスローできる場合に、タスクを再試行します。
SQL の接続接続に失敗した場合、バッチ クラスは正確なエラーを修正する予定です。 TransientSqlConnectionError のタイプに不具合が発生した場合、プラットフォームは問題を認識ではありません。 したがって、対応するバッチ タスクは再試行ではありません。
次の例では、バッチ プラットフォームを再試行できます。
class SampleBatchClass extends RunBaseBatch
{
public void run()
{
try
{
this.batchInfo().parmIdempotent(true);
.....
}
catch(Exception::TransientSqlConnectionError)
{
error("Batch class failed to run.");
throw Exception::Error; //Throwing a new exception
}
}
...
}
これを正しく行う方法を次に示します。
class SampleBatchClass extends RunBaseBatch
{
public void run()
{
try
{
this.batchInfo().parmIdempotent(true);
.....
}
catch(Exception::TransientSqlConnectionError)
{
error("Batch class failed to run.");
throw; //Throwing the same exception
}
}
...
}
バッチ ジョブの再試行メカニズム
- 繰り返し実行されるバッチ ジョブはすべて、失敗するか成功したかどうかに関係なく、自動的に待機中の状態に戻されます。 この動作により、前の実行が失敗した場合に、繰り返しジョブで次の実行時に保留中の作業を実行できます。 この機能は、バッチ ジョブの繰り返し条件が有効な場合にのみ有効にできます。 たとえば、バッチ ジョブの繰り返しの終了日が過ぎない場合は、残りの繰り返しカウントまたは繰り返しの終了日を指定する必要があります。
- 前のオプションとは異なり、このオプションはバッチ ジョブ自体の直接実行再試行ではありません。 これにより、顧客はジョブを再トリガーする前にカスタム ロジックを追加できます。 ジョブの実行が失敗した場合、このロジックは対応するビジネス イベントをリッスンし、失敗を再試行できるかどうかを判断します。 バッチ プラットフォームは、バージョン 10.0.22 (Platform update 46) で Open Data Protocol (OData) アクションを提供します。 エンドポイントへの呼び出しでバッチ ジョブ ID が指定された場合、ジョブは実行に対して再キューされます。 詳細については、バッチ OData API を参照してください。
よくあるご質問
再試行が理由でバッチ タスクが複数の電子メールを送信しない方法はありますか?
再試行が理由でバッチ タスクが複数の電子メールを送信するのを防ぐには、再試行の回数に関係なく、電子メールが 1 回だけ送信されるというメカニズムを実装できます。 考え得る戦略を次に示します:
- トランザクション電子メール サービスを使用します。 メッセージの配信を保証し、重複を回避するための機能を提供するトランザクション電子メール サービスを使用します。 多くの場合、これらのサービスには、タスクが再試行された場合でも重複する電子メールが送信されるのを防ぐ組み込みメカニズムが含まれます。
- メールのステータスを確認します。 電子メールを送信する前に、以前の電子メールの配信のステータスを確認して、同じ電子メールの種類を複数回送信したことがないことを確認します。 電子メールの送信ステータスを追跡し、重複する電子メールが送信されるのを防ぐために、ログまたはデータベース テーブルを管理できます。
- べき等な電子メールの送信を実装します。 電子メール送信プロセスのべき等を作成して、同じ電子メールを複数回送信すると、一度送信する場合と同じ効果が得られます。 電子メールの内容に固有 ID (メッセージ ID やトランザクション ID など) を含めすることで、この結果を得られます。 その後、電子メールを送信する前に ID の存在を確認します。
- 別のランタイム バッチ タスクを使用して電子メールを送信します。 メイン バッチ タスクで、電子メールを送信するための新しいランタイム バッチ タスクを開始します。 バッチ タスクの状態を追跡して、電子メールが正常に送信されたことを確認します。 メイン タスクが再試行される際に、実行タスクの状態を確認して、電子メールが既に送信されているかどうかを確認します。 送信された場合は、送信プロセスをバイパスします。
これらの戦略を 1 つ以上実装することで、再試行が行なくても、バッチ タスクによる電子メールの重複を伴わずに確実に電子メールを送信することができます。
メイン タスクが静的であり、作業を実行する複数のランタイム タスクがキューに入れられます。 再試行は実行タスクに対して行われず、ジョブが正常に完了されたことを確認する方法はありますか?
通常、コントローラーまたはドライバと呼ばれるメイン タスクは、子タスクをキューに入れ直した後すぐに終了する必要があります。 その代わり、子ランタイム タスクの進捗を監視して (たとえば、ループの遅延が15秒のループ内で) 正常に完了する必要があります。 ランタイム タスクが失敗した場合は、新しいランタイム タスクをキューに入れ直して、もう一度操作を実行する必要があります。
コントローラーが各タスクで実行する再試行の回数を管理することが重要です。 この目標を達成するために、専用のテーブルで再試行のログを管理できます。 また、キャプション フィールドを使用してタスク ID を構成して再試行回数を反映することもできます。 過剰な処理や潜在的な問題が発生しないように、再試行を最大 5 回に制限することをお勧めします。
バッチ プラットフォーム再試行ランタイム タスクで SQL の接続エラー以外のエラーが発生しないのはなぜですか?
バッチ プラットフォームでは、次の 2 つの主な理由からランタイム タスクが再試行されません:
- ランタイム タスクは、一時的なメモリ内タスクとして設計され、サーバーの再起動イベントが発生するとクリアされます。 この設計の主な理由は、常に静的なドライバ またはコントローラー クラスが、失敗したランタイム タスクの新しいランタイム タスクをキューに入することで、再起動時に子タスクの再試行を処理するためです。 ランタイム タスクが再試行された場合は、重複するタスクが作成される場合があります。 その結果、突然変異の問題が発生したり、重複したバッチタスクが増えすぎてシステムに負荷がかかったりする可能性があります。
- ランタイムタスクが再試行されると、システム管理が複雑になり、予期せぬ動作につながる可能性があります。 このリスクは、ランタイム タスクによって追加のタスクを作成すると影響が生じ、特に高いリスクです。