ssh开发的查询系统,查询7、8次就变慢,也没有出错信息,为什么?
最近用ssh框架(struts2+spring+hibernate)开发一个查询系统,一张表对应一个查询页面,一共大概10张表,10张表之间没联系,但10张表都通过外键与另一张主表相关联。 表里面也没什么数据
tomcat跑起来后,我查询7、8次后就慢了,并且一直停在那里,我设置断点后,发现它停在: Query query = createQuery(session, sql, null);那里,但没有错误信息输出,所在的方法是分页查询方法:
/**
* 分页查询
* @param sql 查询的sql语句
* @param startRow 分页开始显示的纪录数
* @param pageSize 每页显示的数据条数
* @return
*/
public List find(final String sql,final int startRow,final int pageSize) {
log.debug("querying with no parameter");
try{
List result = this.getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query query = createQuery(session, sql, null);
query.setFirstResult(startRow);
query.setMaxResults(pageSize);
return query.list();
}
});
if (result == null || result.size()==0) {
log.debug("query successful, no result found");
}
else {
log.debug("query successful, result size: " + result.size());
}
return result;
}
catch(RuntimeException e){
log.error("query failed", e);
throw e;
}
}
ssh框架的数据库以及事务配置:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@210.1.4.38:1521:sscdev"/>
<property name="username" value="ssemem"/>
<property name="password" value="ssemem"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="nativeJdbcExtractor" lazy-init="true" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
<bean id="lobHandler" lazy-init="true" class="org.springframework.jdbc.support.lob.OracleLobHandler">
<property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<!-- 一些映射文件的配置-->
<value>com/mem/entity/MmYcMembers.hbm.xml</value>
<value>com/mem/entity/MmItMainOfferMachine.hbm.xml</value>
<value>com/mem/entity/MmItMainInfo.hbm.xml</value>
<value>com/mem/entity/MmItMainOfferDatabase.hbm.xml</value>
<value>com/mem/entity/MmItMainCounterSystem.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.show_sql=false
hbm2ddl.auto=update
hibernate.dialect=org.hibernate.dialect.OracleDialect
</value>
</property>
</bean>
<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="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
<property name="beanNames">
<list>
<value>mainMachineService</value>
</list>
</property>
</bean>
</beans>
不知道什么原因,有没有人可以帮助我;
[解决办法]
一个检索功能不用开启事务吧!
难道有幻读和不可重复读么?
[解决办法]
慢?
一直停在那里,不是慢吧?
[解决办法]
可能你的连接池没有关闭,太多了就会影响速度,也有可能是你把代码调重了
[解决办法]
连接池没关吧.. 有
conn.close()?
[解决办法]
[解决办法]
spring集成hibernate后session会自动关闭的吧?
[解决办法]
session没关,我确定,我也遇到过
[解决办法]
用了spring集成后
get和load可以不用关session
但是query还是要关吧
[解决办法]
没啥,你去看看数据库连接,是不是
1 已经满了
2 有死锁
我认为你的连接没有了,也就是你忘了关闭session来释放连接了。
[解决办法]
你可以试试hibernate中设置二级缓存能不能解决你的问题
[解决办法]
没关闭资源
[解决办法]
你可以对你的代码优化以下了,还可以在 hibernate 中设置缓存
[解决办法]
把PK和显示必要的信息都读到缓存
不要每次翻一页都去读数据库
看信息量,如果是新闻那样的至少应该缓存十页的数据,
[解决办法]
还有就是不要每一次读数据都创建一个QUERY
尽量减少与数据库的交互,
[解决办法]
操作结束后忘了调用session.close()方法了吧
[解决办法]
忘记关闭连接了。连接用完了。
[解决办法]
Spring会自动开启和关闭事务,这个不用担心。
一般保存或更新开启事务就行了,查询是不需要开启事务的。
置于查询速度很慢,可能有以下几点原因:
1.Hibernate没有设置缓存,每次查询、保存、更新都会连接数据库。设置缓存后,如果是更新的话hibernate
会自动同步数据库。如果是保存,保存后hibernate会将新保存的对象放到一级、二级缓存里面,下次更新直接
从缓存拿数据就行了,不用每次都重新读取修改数据库。
2.SessionPool满了,所以会造成长时间等待,可以把poolSize设大点。
3.数据库死锁了,可以参考下所使用的数据库默认支持的事物级别,然后把它设置低一些,可以提高效率,当
然是在保证满足业务需求不会出现问题的情况下。
关于Spring中设置查询方法不开启事务的方法有如下两种:
(1)基于xml方式配置不开启事务:
部分配置如下:
- XML code
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 采用@Transanctional注解方式使用事务 --> <tx:annotation-driven transaction-manager="txManager" /> <bean id="personService" class="com.yakoo5.service.impl.PersonServiceBean"> <property name="dataSource" ref="dataSource" /> </bean> <aop:config> <aop:pointcut expression="execution(* com.yakoo5.service.impl.*.*(..))" id="transanctionPointcut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="transanctionPointcut"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/> <tx:method name="*"/> </tx:attributes> </tx:advice>
[解决办法]
由于以上代码没有正确显示红色,所以在此标注下(在Spring中采用注解方式配置不开启事务):
只需在需要不开启事务的方法前加入如下注解即可:
@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
[解决办法]
学习
[解决办法]
资源的关闭很重要啊,不论 sql或 io 文件读写。。。