场景是这样:
有个提交申请单的操作,需三个动作:新增申请记录表记录、新增申请详单表记录,整个过程需完整,才能提交事务,其中一个过程失败,则需回到操作前状态,采用的是Spring声明式事务配置,但新增申请详单表记录时,由于插入数据量较大,发现用默认的HibernateTemplate里的save方法一条一条记录添加速度较慢,就使用了Hibernate批量插入,发现如果过程无错误,也会提示一个错误:java.lang.IllegalStateException: No value for key [org.hibernate.impl.SessionFactoryImpl@12421db] bound to thread [http-8080-Processor20]
,查了下估计是由于批量插入那边用了Hibernate自带的事务管理,释放了Hibernate下的session,和Spring配置的事务管理有冲突,有没有可以支持Spring自带事务管理,并且支持批量插入大量数据的方法,请教大家如何解决呢?
附上大致代码:
申请Service实现类大致Java代码:
public void applyCard(CardInfo cardInfo, List<CardDetail> cardDetails){ //新增申请记录表记录 applyDAO.saveCardInfo(cardInfo); //新增申请详单表记录 applyDAO.batchSaveCardDetail(cardDetails); }
申请applyDAO实现类的batchSaveCardDetail方法(Hibernate批量插入):
public void batchSaveCardDetail(List<TCardInfo> cardDetails) { Session session = this.getSession(); Transaction tx=null; try{ tx=session.beginTransaction(); for(int i=0;i<cardDetails.size();i++){ session.save(cardDetails.get(i)); if(i%50 == 0){ session.flush(); session.clear(); } } tx.commit();//提交事务 }catch(Exception ex){ ex.printStackTrace(); tx.rollback();//出错则回滚 }finally{ session.close();//关闭session } }
Spring相关配置如下:
<!-- 应用的Spring里的Hibernate事务管理 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- 配置事务拦截器--> <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager" ref="transactionManager" /> <property name="transactionAttributes"> <props> <prop key="applyCard">PROPAGATION_REQUIRED</prop> </props> </property> </bean> <!-- 根据事务拦截器为目标bean自动创建事务代理 --> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>applyService</value> </list> </property> <property name="interceptorNames"> <list> <value>transactionInterceptor</value> </list> </property> </bean> <!-- 申请Service --> <bean id="applyService" class="service.impl.ApplyServiceImpl"> <property name="applyDAO" ref="applyDAO"/> </bean>