Forums: Open Discussion (Thread #32482)

【バッチFW】BLogicで入力データアクセス時にConcurrentModificati (2012-07-10 15:06 by tsadmin #64562)

BLogicで入力データにアクセスしようとするとConcurrentModificationExceptionとなる事象が発生しており困っております。

・FWのバージョンは2.0.2.0。
・トランザクションモデルはSingleTransactionBean。
・入力データは、SELECTの結果を親項目単位でgroupByし、明細部をListに格納する入れ子構造にマッピングしている。
・BLogicのexecuteでその明細部のLISTにアクセスしようとしたところでエラー発生している。
   jp.terasoluna.fw.batch.core.BLogicException: java.util.ConcurrentModificationException
・データの内容によって、このエラーが発生したり、しなかったりする。
  ※データ総件数ではなく、親項目に対しての明細部の量が影響している様子
    データ総件数250万件、1つの親項目につき明細が1千件→エラー発生しない
    データ総件数250万件、1つの親項目につき明細が1万件→エラー発生する

何となくですが
Collectorでまだ明細部のListを作成途中なのに、
その入力データオブジェクトがBLogicに渡されているような気がします・・・

このような事象について回避方法含め何かご存知の方がいらっしゃいましたら、ご教授ください。

Reply to #64562×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RE: 【バッチFW】BLogicで入力データアクセス時にConcurrentModificati (2012-07-12 19:03 by suzukihrzzl #64576)

FW提供のIBatisDbCollectorImplは、
iBATISのRowHandlerを利用して、取得したデータをキューに設定しておりますが、

iBATISのRowHandlerの処理は、1:N構造のオブジェクト完成タイミングではなく
1:N構造を格納するオブジェクトのインスタンスを生成した時に実行される為、
ご連携頂いた例の様な、明細データの量が多い場合において、
List内のデータ完成前(データが欠損した状態)に業務ロジックが処理される問題が発生します。

この問題はIBatisDbCollectorImplの処理に下記変更を加えることで解決致します。
・RowHandler#handleRowに渡された結果を、次回同メソッドが実行されたときに キューに格納する。
・最後に渡された結果は、iBATISが処理を終えた時点でキューに格納する。

さらに、iBATISにて、groupBy属性を利用して1:N構造のオブジェクトを生成させる場合、
全データの取得が終わるまで、全データをiBATIS内部に溜め込みます。
iBATISとしては、
(データがソートされているとは限らず、)
どこまでフェッチすれば1:N構造が完成するのかが分からないため、
全データのフェッチが終わるまではデータを破棄しません。

ですが、SQLを書いている側からすれば、ORDER BY句を設定しているので、
# 設定しているとは思いますが、
# もし設定していなければ設定してください。
# ORDER BY無しでgroupBy属性を利用して大量データを処理する場合、
# 全データを溜め込むだけのメモリが必要になってしまいます。
ローハンドラにn+1個目の1:N構造オブジェクトが渡されたときには、
n個目までの1:N構造オブジェクトは、少なくともiBATISには不要であることが分かります。
# もうそのオブジェクトにデータを追加する必要は無いため。

大量データを処理する際は、
キューにn個目の1:N構造オブジェクトを渡しつつ、
iBATISに残っている情報
# iBATISは必要かもと思っている情報だが、
# SQLを書いている側からすれば不要だと分かる情報
をクリアしてあげる必要があります。


Batch FWの2.0.3.0にて、上記の処理を行う、
1:N専用のコレクタ「IBatisDb1NRelationCollectorImpl」を追加しています。
また、他のバグFIXも行っておりますのでFWをbatch 2系の最新2.0.3.2 (7/12時点)に
更新頂くことを推奨致します。


本事象の対応方法と致しましては、

FWをbatch2.0.3.2に更新後、FrameworkBean.xmlのコレクタ定義に
「IBatisDb1NRelationCollectorImpl」を追加し、groupBy属性を使用している箇所について
コレクタの差し替えを行って頂くことで事象が解消致します。

また、フェーズ的にFWのバージョンを上げることが難しい場合は、

batch 2.0.3.0以降のFWをご参照頂き、IBatisDb1NRelationCollectorImplを
batch 2.0.2.0に積み替えて事象を回避頂く方法となります。

積み替えを行う場合、2.0.2.0と2.0.3.0のCollectorクラスには
一部仕様が異なる個所がございますので、
各々のVerのソースをご参考にご対応をお願い致します。

 主な違いは下記です。
  ・DAOをインジェクションする際の型が異なる。
・RowHandlerを実行するコードが異なる。
・RowHandlerがimplementsする型が異なる。

IBatisDb1NRelationCollectorImpl使用時の注意点につきましては、
batch 2.0.3.2に同梱されているAPIをご参照ください。
Reply to #64562

Reply to #64576×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RE: 【バッチFW】BLogicで入力データアクセス時にConcurrentModificati (2012-08-03 21:06 by tsadmin #64894)

返信が遅くなりましたが、
色々と検討した結果、
問題機能のみFWバージョン2.0.3.2を利用することにしました。

解決できて良かったです。
詳細にご説明いただきありがとうございました。
Reply to #64562

Reply to #64894×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login