2014-12-13 4 views
0

내가 최대 절전 모드 의심이 일괄 처리 최대 절전 모드로, 나는 그들이나는 새로운 오전

말했다 최대 절전 모드 일괄 처리에 대한 몇 가지 튜토리얼을 읽어
Session session = SessionFactory.openSession(); 
Transaction tx = session.beginTransaction(); 
for (int i=0; i<100000; i++) 
{ 
    Employee employee = new Employee(.....); 
    session.save(employee); 

} 
tx.commit(); 
session.close(); 

Hibernate가 모든 지속 된 개체를 캐시합니다 세션 레벨 캐시를 사용하면 궁극적으로 애플리케이션이 50,000 번째 행의 OutOfMemoryException으로 넘어지게됩니다. 이 같은 최대 절전 모드로 일괄 처리를 사용하는 경우에는

Session session = SessionFactory.openSession(); 
Transaction tx = session.beginTransaction(); 
for (int i=0; i<100000; i++) 
{ 
Employee employee = new Employee(.....); 
session.save(employee); 
if(i % 50 == 0) 
{ // Same as the JDBC batch size 
    //flush a batch of inserts and release memory: 
    session.flush(); 
    session.clear(); 
} 
} 
tx.commit(); 
session.close(); 

내 의심의 여지가 대신 외부 세션을 초기화이며,이 문제를 해결할 수 있습니다, 우리는 왜 같은 for 루프에 그것을 초기화 할 수 없습니다

Session session = null; 
Transaction tx = session.beginTransaction(); 
for (int i=0; i<100000; i++) 
{ 
session =SessionFactory.openSession() 
Employee employee = new Employee(.....); 
session.save(employee); 
} 
tx.commit(); 
session.close(); 

올바른 방법입니까, 아니면 올바른 방법이 아니라고 제안하나요?

+0

크기 (50)의 배치를 위해 이러한 개체에 의해 점유 된 메모리를 취소 할 단지에 대한 기사를 발견 [최대 절전 모드에서 일괄 처리] (http://onetouchcode.com/2016/08/21/batch-processing-example-in-hibernate/) – Shailendra

답변

2

아니요 for 루프에서 세션을 초기화하지 마십시오. 새 세션을 시작할 때마다 새 배치가 시작됩니다 (배치 방식이 일종의 배치이므로 비 배치입니다). 또한, 많이 귀하의 방법을 느리게 것입니다. 이것이 첫 번째 예가 "삽입 배치 및 릴리즈 메모리 플러시"가 수행 한 이유 인 첫 번째 예가

if(i % 50 == 0) { 
    //flush a batch of inserts and release memory: 
    session.flush(); 
    session.clear(); 
} 

인 이유입니다.

+0

오! 괜찮아요, 그리고 또 다른 의심 나는 30 사용할 수 있습니다 if (i % 50 == 0) {session.flush(); session.clear();}? –

+1

물론 그렇지만 최적이 아닙니다. 배치 크기 **가 일치해야합니다 **. –

+0

감사합니다. 지금이 개념에 대해 분명히 감사드립니다. –

1

Batch ProcessingHibernate은 거대한 숫자의 작업을 더 작은 작업으로 나눕니다.

session.save(obj)을 실행하면 hibernate는 실제로 객체를 메모리에 캐시하고 (여전히 객체는 데이터베이스에 기록되지 않음) 트랜잭션을 커밋 할 때 데이터베이스에 저장합니다 (transactrion.commit()).

삽입 할 레코드가 수백만 개이기 때문에 session.save(obj)을 실행하면 많은 메모리가 소비되어 결국 OutOfMemoryException이됩니다.

해결책 : 작은 크기의 간단한 배치를 만들어 데이터베이스에 저장하십시오.

if(i % 50 == 0) { 
    //flush a batch of inserts and release memory: 
    session.flush(); 
    session.clear(); 
} 

참고 : 코드에서 session.flush() 위는 flush 즉, 실제로 데이터베이스에 개체를 절약 할 수 및 session.clear()

관련 문제