2013-12-16 2 views
1

전체 폴더 내용을 데이터베이스로 읽는 JAX-RS 웹 응용 프로그램을 만들고 있습니다. 해당 폴더에있는 파일은 매우 클 수 있습니다 (+ -100Mb). JAXB는 xml을 Java 객체로 비 정렬 화하는 데 사용됩니다. 이 객체들은 Hibernate를 사용하여 DB에 저장된다.최대 절전 모드 트랜잭션의 메모리 영향

메모리에 대한 영향을 피하기 위해 전체 파일의 내용을 메모리에 보관하지 않고 스트리밍을 사용하여 개별적으로 각 개체를 처리하기로 결정했습니다.

추가 요구 사항은 폴더가 트랜잭션 방식으로 처리된다는 것입니다. 따라서 XML 중 하나에서 오류가 발생하면 전체 폴더 내용이 오류 폴더로 이동되고 데이터베이스에 이미 추가 된 요소가 롤백됩니다.

이제 내 질문은 최대 절전 모드의 메모리 관리와 관련이있다. 실제 커밋은 (모든 요소가 엔티티 관리자를 사용하여 데이터베이스에 지속 된 후에) 끝나기 때문에 전체 시간 동안 메모리에서 실제로 커밋되도록 데이터를 유지합니다. 그렇다면 폴더에있는 파일의 스트리밍에 어떤 이점이 있습니까? 아니면 DB에 커밋하기 전에 모든 요소가 스프링 트랜잭션에 의해 메모리에 유지되기 때문에 완전히 쓸모 없습니까?

답변

2

Hibernate에서 이런 식으로 스트리밍하고 싶다면 할 수있는 몇 가지가 있습니다.

  • 정기적으로 세션 캐시를 지우십시오. 먼저 메모리 내 캐시를 데이터베이스로 플러시 한 다음 지우는 방법으로 메모리 내 캐시의 내용을 지울 수 있습니다. 한 가지 명심해야 할 점은 1 차 레벨 캐시에서 무언가를 지우면 더 이상 사용할 수 없다는 것입니다 (예를 들어, 객체를 유지할 수없고 지울 수 없으며 1 대 1 - 나중에 많은 연관성). 다음은 매번 캐시를 지우는 간단한 예제입니다. 조금 너무 간단하고 실제로는 50 개 정도의 항목마다 캐시를 ​​지우고 모든 단일 레코드를 플러시하지 않도록해야합니다 (성능 문제가 될 수 있음).
    try { 
        while(...) { 
         processNextRecord(session); 
         session.flush(); 
         session.clear(); 
        } 
        tx.commit(); 
    } catch (Exception ex) { 
        tx.rollback(); 
    } 
    
    • 사용 상태없는 세션

      Transaction tx = session.beginTransaction();

  • . Hibernate의 StatelessSession 객체는 Session 인터페이스와 비슷하지만 약간 다른 방식으로 데이터베이스를 조작 (유지, 수정, 삭제 등) 할 수있게 해준다. 예를 들어 캐스케이드는 존중되지 않으므로 명시 적으로 update 등을 호출해야합니다. 위쪽은 상태없는 세션이 메모리에 아무 것도 저장하지 않는다는 것입니다.

자세한 내용은 Hibernate의 문서 batch processing을 참조하십시오.