2011-11-23 3 views
0

최대 절전 모드를 사용하여 개체를 DB에 저장하려고합니다. DB는 MYSQL 커뮤니티 에디션입니다. 전체 업데이트가 트랜잭션으로 실행됩니다.DB 업데이트 - 장기 실행 작업이 실패합니다.

가이 수행하는 코드이다 :.

getHibernateTemplate를() 될 saveOrUpdate (순서대로);

이 순서가 작은 경우에는 문제가 없지만, 내가 1 개 000 000 항목에 가까이와 함께 시나리오를 테스트 할 때 나는이 문제에 달렸다 :

[email protected]:56:48 DEBUG PersistOrderServiceImpl [flow.ottoImportOrderPlacementInboundFlow.1] - saving order instance:: 
[Order [orderId=080661, vatOrderNumber=SODE000001, orderDate=Tue Nov 08 10:12:37 CET 2011, shippingMethod=STANDARD, .... 

[email protected]:02:12 ERROR JDBCTransaction [flow.ottoImportOrderPlacementInboundFlow.1] - JDBC rollback failed 
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed. 
     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 
..... 
.... 
[email protected]:02:12 ERROR TransactionInterceptor [flow.ottoImportOrderPlacementInboundFlow.1] - Application exception overridden by rollback exception 
java.lang.NullPointerException 
     at com.mysql.jdbc.Field.setConnection(Field.java:972) 
     at com.mysql.jdbc.StatementImpl.getGeneratedKeysInternal(StatementImpl.java:1912) 
     at com.mysql.jdbc.StatementImpl.getGeneratedKeysInternal(StatementImpl.java:1905) 
     at com.mysql.jdbc.StatementImpl.getGeneratedKeys(StatementImpl.java:1885) 
     at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.getGeneratedKeys(NewProxyPreparedStatement.java:1749) 
     at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:97) 
     at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57) 
...... 
...... 

문제가 후에 낸 것 같다 약 5 분 24 초 또는 총 324 초.

MySQL 로그에서 아무 것도 찾을 수 없습니다. 즉 MySQL을 최대 절전 모드 버그의 일종 인 경우

java.lang.OutOfMemoryError: GC overhead limit exceeded 

나도 몰라하거나 일부입니다 :

는 그것은 메모리 나 메모리를 낮출 때 때문에 예외가 다른, 관련이없는 것 같습니다 설정은 업데이트/연결/트랜잭션이 실행될 수있는 시간을 제한합니다.

MySQL 설명서 또는 최대 절전 모드 설정에서 관련없는 것을 찾을 수 없습니다.

나는이 문제를 디버깅하거나 해결하는 데 도움을 주셔서 감사합니다.

해결 : 문제는 내 tomcat lib에있는 파일 c3p0.properties에있었습니다. 다음을 포함합니다 : c3p0.unreturnedConnectionTimeout = 300 어느 정도 시간이 지나면 오류가 발생합니다. 내가 그것을 제거한 후에, 문제는 아무런 문제없이 통과되었다.

+0

그래서 1mil Order 개체를 만들고 최대 절전 모드로 유지할 수 있습니까? 최대 절전 모드의 저장 코드를 게시 할 수 있습니까? –

+0

아니요, 1 백만 개의 아이템이있는 주문을 하나만 만들고 있습니다. 코드를 질문에 게시합니다. –

답변

2

데이터베이스 연결 풀이 시간 초과 값으로 구성되었습니다. 이 시간 초과 값 이전에 트랜잭션이 시작되고 (풀에서 연결을 빌린 경우) 트랜잭션이 완료되지 않으면 (풀에 대한 연결을 해제하지 않음) 데이터베이스 연결 풀 (연결 취소됨으로 표시됨)에 의해 연결이 닫힙니다. hibernate가 트랜잭션을 커밋하려고 시도 할 때 (하이버 네이트는 커넥션이 여기에서 닫혀 있는지 알 수 없다), 드라이버는 예외를 감안한다. 트랜잭션을 더 작은 규모의 트랜잭션으로 세분화하십시오 (항목을 일괄 적으로 커밋하십시오). 모든 주문이 DB에 삽입되면 주문 개체를 삽입하십시오. 그러나 응용 프로그램 코드는 배치 커밋이 실패하고 이후에 롤백 논리를 처리해야합니다.

+0

나는 그 이유를 발견했다고 생각한다. 그것은 내 tomcat lib에있는 c3p0.properties 파일 내에있다. 그것은 다음을 포함합니다 : c3p0.unreturnedConnectionTimeout = 300 이것은 다소 시간이 나간 후에 발생합니다. –

+0

파일을 제거한 후에 문제가 더 이상 존재하지 않습니다. 그래서 당신 말이 맞아요, 그것은 풀링 문제입니다. 감사! –

+0

제한 시간 동안 항목을 제거하면 일부 바람직하지 않은 영향을 줄 수 있으므로주의해야합니다. 이 영구 수정이라고하기 전에 사용중인 드라이버 및 연결 풀의 설명서를 읽으십시오. –