Spring数据流OutOfMemoryError

时间:2019-01-08 22:00:52

标签: jpa stream out-of-memory

我正在尝试流式处理包含200m条记录的表。我进了大约70k,然后收到OutOfMemoryError。这是我的代码:

@Service
@Slf4j
public class Migrator  {

    @Autowired
    LegacyDataRepository legacyDataRepository;

    @Autowired
    Producer producer;

    @Transactional
    public void run() {

        AtomicInteger counter = new AtomicInteger(0);

        try (Stream<Data> stream = legacyDataRepository.readAll()) {

            stream.forEach(x -> {

                try {
                    // the producer converts the data to json and writes to kafka
                    producer.send(data);

                    int currentCount = counter.incrementAndGet();

                    if (currentCount % 1000 == 0)
                        log.info("Migrated {} rows", currentCount);

                } catch (JsonProcessingException e) {
                     log.error("Failed to send event", e);
                }
            });
        }
    }
}

这是我的存储库:

@Repository
@Slf4j
public class LegacyDataRepository {

    @PersistenceContext
    private EntityManager em;

    public Stream<Data> readThreats() {
        return em.createNativeQuery(query, Data.class)
                .setHint(QueryHints.HINT_READONLY, true)
                .setHint(QueryHints.HINT_FETCH_SIZE, 50 )
                // .setFirstResult(0)
                // .setMaxResults(1000)
                .getResultStream();
    }
}

在其他示例中,我发现这似乎是如何流式传输大表的整体。

EDIT1: 我怀疑@Transactional保留了流中正在读取的所有记录。我添加了对EntityManager的引用,并添加了em.clear();,以保持对内存的检查。我真的很想解决这个更好的方法。

如何在不保留实体管理器中的实体的情况下读取流?

0 个答案:

没有答案