场景是这样:
有个提交申请单的操作,需三个动作:新增申请记录表记录、新增申请详单表记录,整个过程需完整,才能提交事务,其中一个过程失败,则需回到操作前状态,采用的是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>