Programing/JAVA

Java 대용량 데이터 DB 처리 방법, batch

리커니 2021. 10. 8. 14:34
반응형

Java 대용량 데이터 DB 처리 방법, batch

 

많은 양의 데이터를 insert 하거나 update 해야 할 때 

mybstis dynamic query를 사용하게 되면 메모리 에러가 발생할 수 있습니다.

 

이럴 때 사용할 수 있는 방법이 batch를 활용한 방법인데요.

이번 포스팅에서는 그 사용법과 mybatis dynamic query와 비교를 해보도록 하겠습니다.

 

우선 프론트에서 Json Array로 다량의 데이터를 받아 데이터를 update 한다고 하면

아래와 같이 dynamaic query를 활용할 수 있습니다.

 

<update id="dynamicUpdate" parameterType="HashMap">
    <foreach item="item" collection="배열이 들어있는 맵의 키" open="DECLARE BEGIN" close=";END;" separator=";">
        UPDATE 테이블명
           SET 컬럼 = #{item.column}
         WHERE 테이블키 = #{item.key} 
    </foreach>
</update>

 

이 방법은 반복문을 돌면서 update 쿼리를 붙여 PL/SQL 문을 만들어 실행하는 방법인데요.

데이터의 양이 많을 수록 메모리 부하가 일어날 확율이 높습니다.

 

요즘에야 워낙 하드웨어의 성능이 좋아 많은 리소스를 활용할 수 있다면 문제가 발생하지 않겠지만,

제한적인 환경에서 실행하면 문제가 됩니다.

그리고 처리 속도도 느립니다.

 

그럼 이보다 다량의 데이터를 처리할 때 효율적인 방법인 batch를 활용한 방법을 알아보겠습니다.

 

@Service("business")
public class business{
    private PreparedStatement pstmt;
    private Connection con;
    
    @Transactional
    public void testLogic(Map<String, Object> map) throws Exception{
        con = null;
        pstmt = null;
        String sql = "UPDATE 테이블명 SET 컬럼 = ? WHERE 테이블키 = ?";
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            con = DriverManager.getConnection("jdbc:oracle:thin:@ip:port/sid","id","pw");
            pstmt = con.prepareStatement(sql);
            
            /*json to list*/
            List<Map<String, Object>> list = CmmnVar.GSON.fromJson(map.get("data").toString(), ArrayList.class);
            for(int i=0, n=list.size(); i<n; i++){
                pstmt.setString(1, list.get(i).get("param1").toString));
                pstmt.setString(2, list.get(i).get("param2").toString));
                pstmt.addBatch();
                pastmt.clearParameters();
                
                /*100개 마다 commit*/
                if((i%100) == 0){
                    pstmt.executeBatch();
                    pstmt.clearBatch();
                    con.commit();
                }
            }
            pstmt.executeBatch();
            con.commit();
        }catch(Exception e){
            con.rollback();
        }finally{
            if(pstmt != null) pstmt.close();
            if(con != null) con.close();
        }
    }
}

 

DB 커넥션 정보를 따로 설정하고, 전달받은 데이터를 반복문을 돌면서 100개마다 커밋을 하는 방식입니다.

500개 데이터로 체크해봤을 때 dynamic query를 사용했을 때보다 0.3초 정도 빠른것으로 확인됐습니다.

데이터가 많아질 수록 차이도 커지겠죠.

 

다량의 데이터를 처리할 때는 batch 방식을 사용하도록 합시다!

 

 

 

 

 

 

 

 

반응형