[Talend] 繰り返し処理中のエラーでも処理を継続するには

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

繰り返し処理中にエラーが発生した場合であっても最後まで処理を継続させたい、といった事は多々あるものと思います。

しかし、普通にジョブを作成しただけでは意図した動作をしてくれません。

通常の繰り返しジョブ

tLoop コンポーネントを利用して 1 から 10 まで繰り返し、その数値を標準出力します。その中で、数値が 3 になった際に例外が投げられるように作成しています。

ss_20151221173144

int currentValue = ((Integer)globalMap.get("tLoop_1_CURRENT_VALUE"));

System.out.println(currentValue);

if (currentValue == 3) throw new Exception();
ジョブ example_iterate_main_1 を 18:45 21/12/2015 に開始しました。
[statistics] connecting to socket on port 4031
[statistics] connected
1
2
3
Exception in component tJava_1
java.lang.Exception
	at local_project.example_iterate_main_1_0_1.example_iterate_main_1.tLoop_1Process(example_iterate_main_1.java:1048)
	at local_project.example_iterate_main_1_0_1.example_iterate_main_1.runJobInTOS(example_iterate_main_1.java:1329)
	at local_project.example_iterate_main_1_0_1.example_iterate_main_1.main(example_iterate_main_1.java:1186)
2015-12-21 18:45:45|16xUU8|16xUU8|16xUU8|LOCAL_PROJECT|example_iterate_main_1|Default|6|Java Exception|tJava_1|java.lang.Exception:null|1
[statistics] disconnected
ジョブ example_iterate_main_1 が 18:45 21/12/2015 に終了しました。 [終了コード=1]

3 を最後に処理が停止してしまいました。

繰り返しを継続するジョブ

処理の内容は前段のものと同様です。

親ジョブ(example_iterate_main_2)

ss_20151221174451

子ジョブ(example_iterate_sub)

ss_20151221174611

int currentValue = context.currentValue;

System.out.println(currentValue);

if (currentValue == 3) throw new Exception();

※カウント値は親ジョブからコンテキスト値として受け取ります。

ジョブ example_iterate_main_2 を 18:46 21/12/2015 に開始しました。
[statistics] connecting to socket on port 3438
[statistics] connected
Exception in component tJava_1
java.lang.Exception
	at local_project.example_iterate_sub_0_1.example_iterate_sub.tJava_1Process(example_iterate_sub.java:356)
	at local_project.example_iterate_sub_0_1.example_iterate_sub.runJobInTOS(example_iterate_sub.java:1263)
	at local_project.example_iterate_sub_0_1.example_iterate_sub.runJob(example_iterate_sub.java:1117)
	at local_project.example_iterate_main_2_0_1.example_iterate_main_2.tLoop_1Process(example_iterate_main_2.java:426)
	at local_project.example_iterate_main_2_0_1.example_iterate_main_2.runJobInTOS(example_iterate_main_2.java:717)
	at local_project.example_iterate_main_2_0_1.example_iterate_main_2.main(example_iterate_main_2.java:574)
1
2
3
2015-12-21 18:46:16|yoYQAL|cn360X|cn360X|LOCAL_PROJECT|example_iterate_sub|Default|6|Java Exception|tJava_1|java.lang.Exception:null|1
4
5
6
7
8
9
10
[statistics] disconnected
ジョブ example_iterate_main_2 が 18:46 21/12/2015 に終了しました。 [終了コード=0]

処理は 10 まで継続しています。

ポイント

ポイントは「繰り返し対象処理を別ジョブにする」ことです。

繰り返しの対象処理である「数値を標準出力する処理」を子ジョブへ抜き出し、親ジョブ上の繰り返し始端コンポーネントに接続された tRunJob から呼び出します。

その際、「子のエラーで停止」チェックボックスのチェックを外します。

ss_20151221180837

親ジョブの tLoop で生成されるカウント値は、コンテキスト値として子ジョブへ渡します。

なお、親へはエラーが通知されなくなるのでエラーで何らかの処理を行う(メール通知など)場合は子ジョブで用意する必要があります。

まとめ

親ジョブ・子ジョブの階層が深くなりすぎたり個数が増えるとジョブの見通しが悪くなってしまいます。規模にもよりますが、階層数・子ジョブ数は最小限となるように設計すると見やすい Talend ジョブになるかと思います。