[하이버네이트 배치 추가] flush와 clear

배치 작업이라는 것이 DB에서 데이터를 읽어온 다음 뭔가 수정하고 뭔가를 다시 DB에 넣는 작업인데 이런 작업을 하이버네이트로 할 때 조심해야 할 것이 있습니다.

                InvDailyClosing invDailyClosing = new InvDailyClosing();
                invDailyClosing.setDate(today);
                invDailyClosing.setLocation(location);
                invDailyClosing.setItem(item);
                invDailyClosing.setQtyStart(qtyStart);
                invDailyClosing.setInvInList(invInList);
                invDailyClosing.setInvOutList(invOutList);
                invDailyClosing.closing();
                dao.add(invDailyClosing);
이렇게 작성하면 끝난것 같지만 사실 좀 위험한 코드입니다. 만약 저 코드가 for 루프 안에 있고 굉장히 여러번 반복 된다면 언젠가는 MemoryOutOfException을 보게 될 겁니다. “아니 왜?” 라고 하시는 분들이 계실텐데요. 
흠… 하이버네이트 1차 캐시 때문에 그런 현상이 생깁니다. 하이버네이트는 Persistent 상태의 객체를 하이버네이트 Session에 담아둡니다. 여기사 1차 캐시입니다. 캐시니까 저안에 담아놓고 재사용할 수 있습니다. DB에 다녀오는 횟수를 줄일 수 있겠죠. 그런데 언젠가는 이 캐시를 DB와 동기화 시켜야 합니다. 그래야 Session에 담겨있는 객체(Pesistent 객체)를 지지고 볶은 것이 DB에 반영이 되겠죠. 그렇게 DB와 Session 상태를 동기화 시키는것을 Flush라고 하는데.. 또 Persistent 상태라는 것은… 아.. 이런.. 안되겠군요. @_@ 그냥 하이버네이트 완벽 가이드를 읽어주세요.
아무튼 너무 많이 쌓여서 메모리가 부족해지는 상황이 발생하지 않도록 계속해서 Session을 DB에 동기화 시키고 Session을 비워주는게 좋습니다.
하이버네이트 Session의 flush()와 clear()이 바로 그런 용도로 존재하죠. 그래서 
                InvDailyClosing invDailyClosing = new InvDailyClosing();
                invDailyClosing.setDate(today);
                invDailyClosing.setLocation(location);
                invDailyClosing.setItem(item);
                invDailyClosing.setQtyStart(qtyStart);
                invDailyClosing.setInvInList(invInList);
                invDailyClosing.setInvOutList(invOutList);
                invDailyClosing.closing();
                dao.add(invDailyClosing);
             dao.flushAndClear();

이렇게 하이버네이트용 GenrericDao에 flushAndClear()라는걸 만들어 놓고 써주면 됩니다. 주의하실 것은… 반드시 flush 먼저 하고 나서 clear 해야 합니다. 반대로 하면 음식 담긴 쟁반을 서빙도 안하고 설것이 해버리는거나 마찬가지..

2 thoughts on “[하이버네이트 배치 추가] flush와 clear”

  1. 난 개인적으로 배치는 pl/sql 추천! 데이터베이스의 성능을 최대한 이용하는것을 더 선호하는편이얌. 특히 대형사이트에서 자바배치 돌리는건 상당히 무모해보인다는. ^^;;; 새벽에 다 돌아줘야하는 배치들이 아침까지 돌고있거나 순차적으로 돌아야하는 디펜던시 걸려버리면 진짜 답 안나옴 –;; 쿼리도 oltp성이냐 아니냐에따라 플랜을 다르게 가져가야 하듯이 배치도 상황에따라 수행주체를 바꿔줘야할 필요성이 있는것같오. ㅋㅋ. 생각이 그렇다는거~~ 아무래도 내가 디비도 좋아하다보니 이런글에 굳이 덧글달고 있는듯 ^^;;;

    1. 티스토리가 이상하네요. 댓글 달렸는데 제목 목록에 표시도 안되고 댓글 목록에도 표시가 안되고.. 흠..

      전 딱히 배치를 꼭 자바로 하자 DB로 하자는 주위는 아닌데 아직 배치 로직 검증 단계라.. (일단 제가 후딱 해볼 수 있는)자바로 배치 로직짜서 검증하고 나중에 그걸 SQL로 바꾸던지 해도 될 것 같네요.

      대용량이 아니라 하더라도 20초면 될 일을 20분 동안 하게 되는 사태는 벌어지면 안되겠죠.

Leave a Reply

Your email address will not be published. Required fields are marked *