![](/img/trans.png)
[英]Hibernate : Transaction Commit time exception (Could not execute JDBC batch Update)
[英]Could not commit Hibernate transaction
我是休眠的新手。 我正在嘗試編寫一種方法,該方法將插入或更新50條記錄,然后提交並再次繼續插入。 我這樣做是因為,如果在插入最后一條記錄時發生了某些事情,我想保留數據庫中所有以前的記錄。
這就是我在做什么:
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs){
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =false;
for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs){
if(sessionEnded){//At the very beginning, the transaction remains open dont know why. So session.getTransaction().begin() causing exception
session.getTransaction().begin();
sessionEnded = false;
}
session.saveOrUpdate(storeDetailsDTOTmp);
if ( ++count % 10 == 0 ) { //If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size. Total rows inserted/updated till now: "+ count);
session.getTransaction().commit();
session.flush();
session.clear();
sessionEnded =true;
} else if(count == storeDetailsDTOs.size()){
session.getTransaction().commit();
session.flush();
session.clear();
}
}
logger.info("Insertion completed. Total rows inserted/updated: "+ count);
return true;
}
這工作正常,但是執行此方法后發生異常。 因此,此方法的返回值永遠不會返回到調用方法。 誰能幫我? 堆棧跟蹤:
com.follett.fd.exception.UniversityWithSimilarAdoptionException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
at com.follett.fd.service.impl.FFDServiceImpl.populateLocation(FFDServiceImpl.java:194) ~[classes/:na]
at com.follett.fd.controller.FFDServiceController.populateLocation(FFDServiceController.java:74) ~[classes/:na]
at com.follett.fd.controller.FFDServiceController$$FastClassBySpringCGLIB$$2f892fae.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:173) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at com.follett.fd.controller.FFDServiceController$$EnhancerBySpringCGLIB$$f350f456.populateLocation(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:871) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) [tomcat-embed-core-7.0.30.jar:7.0.30]
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) [tomcat-embed-core-7.0.30.jar:7.0.30]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_25]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_25]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25]
僅當sessionEnded
為true
時才打開會話,但僅在session.getTransaction().commit()
之后將其設置為true
。 更好的解決方案是在循環外部開始和結束會話。
我把@Transactional
放在了班級。 我不確定這是引起問題的原因,但我不確定。 刪除它之后,我在執行時遇到一些錯誤: this.hibernateSessionFactory.getCurrentSession();
。 我想我必須為此設置一個屬性。
無論如何要實現我想要的我修改了方法:
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs){
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =false;
for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs){
session.saveOrUpdate(storeDetailsDTOTmp);
//session.evict(storeDetailsDTOTmp);
if ( ++count % 50 == 0 ) { //If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size.");
session.flush();
session.clear();
}
}
return true;
}
我要插入50條記錄后調用此方法。 請注意,修改方法后,我在類級別保留了@Transactional
批注。
謝謝大家的幫助!
這是代碼,您可以在50條記錄之后將記錄刷新到DB中,但是在發生故障的情況下會全部提交/回滾(通常是這種情況),但是如果您要提交50條記錄,則在清除后執行commit。
public void insert(List<T> items) {
//begin transaction
for (int i = 0; i < items.size(); i++) {
T item = items.get(i);
session.save(item);
if (i % 50 == 0) {
session.flush();
session.clear();
}
}
session.flush();
session.clear();
//commit transaction
}
標志檢查中有一個錯誤,使事務無法開始。 我已經進行了更改,希望這會起作用。
@Override
public boolean updateStoreDetails(List<StoreDetailsDTO> storeDetailsDTOs)
{
Session session = this.hibernateSessionFactory.getCurrentSession();
int count = 0;
boolean sessionEnded =true; for(StoreDetailsDTO storeDetailsDTOTmp : storeDetailsDTOs)
{
if(sessionEnded)
{
session.getTransaction().begin(); sessionEnded = false;
} session.saveOrUpdate(storeDetailsDTOTmp) ;
if ( ++count % 10 == 0 )
{
//If batch size is 50 clear session-level cache & to avoid OutOfMemoryException
logger.info("Clearing session after 50 batch size. Total rows inserted/updated till now: "+ count);
session.getTransaction().commit();
session.flush(); session.clear();
sessionEnded =true;
}
else if(count == storeDetailsDTOs.size()){
session.getTransaction().commit();
session.flush();
session.clear();
}
}
logger.info("Insertion completed. Total rows inserted/updated: "+ count);
return true;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.