DAO 클래스에 다음 트랜잭션 단위를 사용하여 최대 절전 모드로 여러 행을 삽입하려고합니다.Hibernate에 일렬로 삽입 - 배치 삽입
@Override
@SuppressWarnings("unchecked")
@Transactional(readOnly = false, propagation=Propagation.REQUIRES_NEW, rollbackFor={Throwable.class})
public String insertZoneCharge(Long zoneId, List<Object[]> items)
{
Session session=sessionFactory.openSession();
session.beginTransaction();
//Configuration configuration=new Configuration();
//configuration.setProperty("hibernate.jdbc.batch_size", "50");
int i=1;
for(Object[] o:items)
{
if(o[2]!=null&&StringUtils.isNotBlank(o[2].toString()))
{
ZoneChargePK zoneChargeId=new ZoneChargePK();
zoneChargeId.setWeightId(Long.parseLong(o[0].toString()));
zoneChargeId.setZoneId(zoneId);
model.ZoneCharge zoneCharge=new model.ZoneCharge();
zoneCharge.setZoneChargePK(zoneChargeId);
zoneCharge.setCharge(new BigDecimal(o[2].toString()).setScale(2, RoundingMode.HALF_UP));
session.save(zoneCharge);
if(++i%50==0)
{
session.flush();
session.clear();
}
}
}
session.getTransaction().commit();
session.close();
return "Data saved successfully.";
}
이 매개 변수의 매개 변수는 JSON 요청을 통해 제공됩니다. 관련이 없기 때문에 오라클 테이블 세부 사항에 대해서는 자세히 설명하지 않습니다.
내가 3 개의 값을 제공한다고 가정하면이 루프는 3 회 반복되고 3 개의 행이 해당 데이터베이스 테이블에 생성됩니다. 트랜잭션이 성공적으로 완료되면 콘솔에서 볼 수있는 다음 기본 Oracle INSERT
문이 세 번 실행됩니다.
insert into WAGAFASHIONDB.ZONE_CHARGE (CHARGE, WEIGHT_ID, ZONE_ID) values (?, ?, ?)
디버그 및 추적 정보는 다음과 같습니다.
DEBUG [http-apr-8080-exec-84] (SqlStatementLogger.java:104) - insert into WAGAFASHIONDB.ZONE_CHARGE (CHARGE, WEIGHT_ID, ZONE_ID) values (?, ?, ?)
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [1] as [NUMERIC] - 1.00
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [2] as [BIGINT] - 164
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [3] as [BIGINT] - 22
DEBUG [http-apr-8080-exec-84] (SqlStatementLogger.java:104) - insert into WAGAFASHIONDB.ZONE_CHARGE (CHARGE, WEIGHT_ID, ZONE_ID) values (?, ?, ?)
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [1] as [NUMERIC] - 2.00
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [2] as [BIGINT] - 221
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [3] as [BIGINT] - 22
DEBUG [http-apr-8080-exec-84] (SqlStatementLogger.java:104) - insert into WAGAFASHIONDB.ZONE_CHARGE (CHARGE, WEIGHT_ID, ZONE_ID) values (?, ?, ?)
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [1] as [NUMERIC] - 3.00
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [2] as [BIGINT] - 163
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [3] as [BIGINT] - 22
그래서, INSERT
세 개의 문이 실행 된 데이터베이스에 별도의 세 가지 여행이되었습니다 것으로 보인다.
한 번에 다중 행 INSERT
문 하나만 실행하면됩니다. 이 상황에서 Hibernate는 실제로 세 개의 분리 된 문장을 실행 하는가? 그렇다면 특정 배치에서 명령문을 실행하는 방법은 무엇입니까? 내 코드에 문제가 있습니까?
application-context.xml
의 내 최대 절전 모드 구성은 다음과 같습니다.
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
hibernate.jdbc.batch_size=50
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
hibernate.format_sql=false
hibernate.show_sql=true
hibernate.order_updates=true
hibernate.connection.autocommit=false
hibernate.order_inserts=true
hibernate.order_updates=true
hibernate.cache.use_query_cache=false
hibernate.cache.use_second_level_cache=false
javax.persistence.validation.mode=callback
</value>
</property>
'Configuration configuration = new Configuration(); configuration.setProperty ("hibernate.jdbc.batch_size", "50");'는 의미가 없습니다. SessionFactory를 생성하면이를 수행해야합니다. –
@orid -이 문장을 주석 처리했습니다. [이 답변] (http://stackoverflow.com/a/8310442/1391249)은 "* 트랜잭션이 완료 될 때까지는 ** 영구적으로 ** 만들지 않았습니다 **"라고 말합니다. 따라서 데이터베이스를 한 번만 방문하면이 작업을 수행 할 수 있습니까? – Tiny