JpaPagingItemReader

By | 2022년 9월 23일
Table of Contents

JpaPagingItemReader

페이징 방식에는 두가지 문제가 있다.

  1. 페이지가 무지 커지게 되면 성능문제가 발생한다.

  2. 어디까지 가져왔는지 표시하면서 데이타를 가져오게 되면 가져오지 못하는 데이타가 발생한다.

SELECT e
FROM SrcItemEntity e JOIN SrcItemTransferEntity t ON e.id = t.itemid
WHERE t.transferDate <= e.modifiedAt
ORDER BY e.id

위와같은 쿼리로 데이타를 가져오고,
transferDate 를 수정하게 되면,
처음 1~10개 가져온 후 transferDate 를 수정하게 되면
다음 2번째 페이지를 가져올때
11~20이 아니라 21~30 을 가져오게 된다.

이 문제를 해결하기 위해 getPage() 를 수정해서,
항상 첫번째 페이지만 가져오도록 수정할 수 있다.

@Slf4j
@Configuration
public class SrcItemReader {

    private final EntityManagerFactory entityManagerFactory;

    public SrcItemReader(@Qualifier("ServerEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    @Value("${batch.read-product.size}")
    private int readProduct;

    @Bean
    public JpaPagingItemReader<SrcItemEntity> readForUpdate() {

        JpaPagingItemReader<SrcItemEntity> reader = new JpaPagingItemReader<>() {
            @Override
            public int getPage() {
                return 0;
            }
        };

        try {
            reader.setQueryString(
                    " SELECT e "
                            + " FROM SrcItemEntity e JOIN SrcItemTransferEntity t ON e.id = t.itemid  "
                            + " WHERE t.transferDate <= e.modifiedAt "
                            + " ORDER BY e.id "
            );
            reader.setPageSize(readProduct);
            reader.setName("readForUpdate");
            reader.setEntityManagerFactory(entityManagerFactory);
        } catch (Exception e) {
            throw new RuntimeException("Unknown exception occurred", e);
        }

        return reader;
    }

    @Bean
    public JpaPagingItemReader<SrcItemEntity> readForInsert() {

        JpaPagingItemReader<SrcItemEntity> reader = new JpaPagingItemReader<>() {
            @Override
            public int getPage() {
                return 0;
            }
        };

        try {
            reader.setQueryString(
                    " SELECT e "
                            + " FROM SrcItemEntity e LEFT JOIN SrcItemTransferEntity t ON e.id = t.itemid  "
                            + " WHERE t.itemid is NULL "
                            + " ORDER BY e.id "
            );
            reader.setPageSize(readProduct);
            reader.setName("readForInsert");
            reader.setEntityManagerFactory(entityManagerFactory);
        } catch (Exception e) {
            throw new RuntimeException("Unknown exception occurred", e);
        }

        return reader;
    }
}

답글 남기기