0

私の状況:

私はreaderItemでdbから読んだクラスAを持っています。次に、このクラス A を処理し、itemProcessor で行っているクラス B を作成する必要があります。最後に、このクラス B を itemWriter の db に保存します。

問題: 処理中に、クラス B の外部キーを持つクラス C (約 1 ミルのレコード) を作成し、このクラス C を保存する必要もあります。

私はこのようなことをすることはできません:私が書いたように、約2GBのスペースをメモリに保存する必要がある約1ミルのレコードがあるからです。SOこの問題をどのように解決すればよいですか。

public class BWriter extends BaseItemWriter<B> {

    public void write(List<? extends B> data) throws Exception {
        logger.info("Start writing: " + data);
        for (B item : data) {
            myCustomDao.saveB(item);
            for (C itemC : item.getC()) {
                itemC.setB(item);
                myCustomDao.saveC(itemC);
            }
        }
    }
}

アップデート:

私が欲しい春のバッチを含まない可能な解決策:

    List<C> cList = new ArrayList<C>();
    int i = 0;
    String line;
    while ((line = reader.readLine()) != null) {
        String[] data = line.split(";");
        if (data.length > 1 && !StringUtils.isBlank(data[1])) {
            C cItem = new C();
            cItem.set(...);
            cList.add(i, cItem);
            if (++i >= 1000) {
                myCustomDao.save(cList);
                cList = new ArrayList<C>();
                i = 0;
            }
        }
    }
  if (!cList.isEmpty())
                myCustomDao.save(cList);
4

1 に答える 1

0

commit-interval1 つの B 要素が最大 1mil の C オブジェクトを持つことができるため、オプションではない小さな値に減らすと、それを行うことができます。

処理された B オブジェクトに C オブジェクトを作成せずに、クラス A をクラス B に処理します。アタッチでは
、 C オブジェクト (リスナーでの受信に関連) を 1 つずつ作成/保存するため、メモリ消費量は少なくなりますが、トランザクション境界での作業が保証されます。BWriterItemWriteListener<B>.afterWrite()List<B>

問題がプレーンな JDBC の代わりに Hibernate を使用したことが原因である場合は、ステートレス セッションまたはflush()/clear()セッションを手動で使用することを考えることができます。データベースの 1mil レコードは大した数で
はありません 残念ながら、大量のデータがある場合、ORM は最良の選択ではありません。

私の2セント、私はあなたと同じようにSpring-batchを初めて使用します。

于 2013-08-27T11:52:18.413 に答える