SSH 连续8次以上查询卡住了

awusoft 2009-02-16 01:42:12
我有一个项目使用SSH框架
web.xml:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml,/WEB-INF/common.xml,/WEB-INF/basic-spring.xml,/WEB-INF/system-spring.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>false</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


spring配置文件:

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="com.microsoft.jdbc.sqlserver.SQLServerDriver">
</property>
<property name="url"
value="jdbc:microsoft:sqlserver://localhost;databasename=sdwms">
</property>
<property name="username" value="sa"></property>
<property name="password" value=""></property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<bean id="baseTransaction" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="proxyTargetClass" value="true"/>
<property name="transactionAttributes">
<props>
<prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="count*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="execute**">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="preAdd*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="listDel*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>


相关Bean注入:

<bean name="commonDao" class="com.szdzsoft.dao.impl.CommonDaoImple">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<!-- 货品单位 -->
<bean name="produnitService" parent="baseTransaction">
<property name="target">
<ref bean="produnitServiceTarget" />
</property>
</bean>
<bean id="produnitServiceTarget"
class="com.xxx.service.impl.basic.ProdunitServiceImpl"
abstract="false" lazy-init="default" autowire="default"
dependency-check="default">
<property name="commonDao">
<ref bean="commonDao" />
</property>
</bean>
<bean name="/produnit" class="com.xxx.web.action.basic.ProdunitAction">
<property name="customerService">
<ref bean="customerService"/>
</property>
<property name="produnitService">
<ref bean="produnitService"/>
</property>
</bean>


Action中代码

public ActionForward update(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
request.setAttribute("units",this.unitService.listBsProdunitAll());
request.setAttribute("units",this.unitService.listBsProdunitAll());
request.setAttribute("units",this.unitService.listBsProdunitAll());
request.setAttribute("units",this.unitService.listBsProdunitAll());
request.setAttribute("units",this.unitService.listBsProdunitAll());
request.setAttribute("units",this.unitService.listBsProdunitAll());
request.setAttribute("units",this.unitService.listBsProdunitAll());
request.setAttribute("units",this.unitService.listBsProdunitAll());
request.setAttribute("units",this.unitService.listBsProdunitAll());
request.setAttribute("units",this.unitService.listBsProdunitAll());
return mapping.findForward("update");
}

unitService.listBsProdunitAll()方法:

public List listBsProdunitAll(){
return commonDao.executeQuery("from BsProdunit o order by id");
}

commonDao.executeQuery(String)方法:

public List executeQuery(final String hql, final Object[] param, final int start, final int pageSize)
{
return (List)getHibernateTemplate().execute(new HibernateCallback()//这里使用了匿名内部类
{
public Object doInHibernate(Session session)//Spring进行事务维护 省去每次创建session和关闭session
throws HibernateException
{
// TODO Auto-generated method stub
List list = new ArrayList();
if(hql==null || hql.equals(""))
{
return list;
}
//System.out.println(hql);
Query query = session.createQuery(hql);
if(hql.indexOf("?")>0 && param!=null && param.length>0)
{
//System.out.println(hql+"++++++++++++++++++"+param[0]);
//query.setParameter(0,"aaa" );
//query.setp
for(int i=0;i<param.length;i++)
{
query.setParameter(i, param[i]);
}
}else if(hql.indexOf(" ?")<0 && param!=null)
{
return list;
}
if(start>=0 && pageSize>0)
{
query.setFirstResult(start);
query.setMaxResults(pageSize);
}
list = query.list();
session.clear();
return list;
}
}, true);
}

public List executeQuery(String hql, Object[] param) {
// TODO Auto-generated method stub
return this.executeQuery(hql, param, -1,-1);
}

public List executeQuery(String hql) {
// TODO Auto-generated method stub
return this.executeQuery(hql, null);
}


问题:
现在执行Action中的update方法时,卡住了,页面一直在等等.像是数据库被锁住一样.
如果说Aciton中的那些代码request.setAttribute("units",this.unitService.listBsProdunitAll());少于等于8次就没有问题.大于8次就会卡住.不知道为什么?
解决办法:在Spring与数据库的连接地方加上

<property name="maxActive">
<value>0</value>
</property>
<property name="maxIdle">
<value>30</value>
</property>
<property name="maxWait">
<value>10000</value>
</property>

这样就好,不知道为什么,感觉像是数据库最大连接数的问题,如果说真是这样,那么我是配置了一个请求一个session的,应该一个连接就够了吧?在不加这些参数的时候,少于8次却是好的,这又是为什么呢?忘高人指教.哪位菜鸟们也学了SSH的也来参与一下
还有一个问题,web.xml中
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这里的/*不知道有没有关系?请求一张图片也会做这个操作么?还是如果线程中已经有了,就不放了?有可能是请求一张图片,一个Action,一个JSP.
...全文
617 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
jj_8305 2009-06-19
  • 打赏
  • 举报
回复
加了楼主的代码后 出现以下错误:
Cannot open connection
Cannot get a connection, pool error Timeout waiting for idle object
Timeout waiting for idle object
JavaCostar001 2009-06-05
  • 打赏
  • 举报
回复
非常好的帖子,看来还要更详细的学习一下hibernate了 ,谢谢了
老紫竹 2009-02-17
  • 打赏
  • 举报
回复
去看看是否有数据库死锁!
awusoft 2009-02-16
  • 打赏
  • 举报
回复
恩,现在是做一些简单的系统,事务不是太复杂了.
awusoft 2009-02-16
  • 打赏
  • 举报
回复
恩,现在是做一些简单的系统,事务不是太复杂了.
esena 2009-02-16
  • 打赏
  • 举报
回复
你的事务交给spring托管时,在事务开始时spring打开数据库事务并且自动提交被关闭,直到事务结束时spring才会
帮助把数据库事务提交

期间的数据库联接是不中断的,只会占用联接迟中的一个连接

建议你可以了解一下spring的事务机制,比我说的详细,但原理大致如此
awusoft 2009-02-16
  • 打赏
  • 举报
回复
恩,事务不一样,Service层一个方法一个事务了
esena 2009-02-16
  • 打赏
  • 举报
回复
你说的这两种情况应该是一样的,因为在同一个事务中,但之前的两种是绝对不一样的,他们是事务独立的
awusoft 2009-02-16
  • 打赏
  • 举报
回复

中的commonDao.executeQuery("from BsProdunit o order by id");
循环执行10遍,把Action中保留一个,你看还能一样?

外边调用10次,和这里调用10次是一样的吧??
在executeQuery里调用10次才不一样吧??
commonDao.executeQuery("from BsProdunit o order by id");
commonDao.executeQuery("from BsProdunit o order by id");
commonDao.executeQuery("from BsProdunit o order by id");
commonDao.executeQuery("from BsProdunit o order by id");
commonDao.executeQuery("from BsProdunit o order by id");
commonDao.executeQuery("from BsProdunit o order by id");
不是一样的吗????
awusoft 2009-02-16
  • 打赏
  • 举报
回复
我说的就是Hibernate的session,不是Http的session;
我现在又测试了一下发现这里的问题:
<init-param>
<param-name>singleSession</param-name>
<param-value>false</param-value>
</init-param>

这个帖子说设置为false就是不使用......
http://topic.csdn.net/u/20080227/15/2b94bb63-4ee7-494f-b0f6-0bfc6825c4da.html
然后我设置为true果然可以了.
我先去试试了
esena 2009-02-16
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 AWUSOFT 的回复:]
经过我测试后发现maxActive在作怪.
OpenSessionInViewFilter 不是用来设置一个请求一个session的吗?在我请求一个Action的过程的时候,应该是一个线程吧.不管这个Action的方法进行多次查询,它都应该在同一个线程里啊.
我现在也是把事务设置在service(manager)了吧?
[/Quote]
你设置的session是server的session吧,我说的是数据库联接的session,二者不一样的,
不信你把
public List listBsProdunitAll(){
return commonDao.executeQuery("from BsProdunit o order by id");
}
中的commonDao.executeQuery("from BsProdunit o order by id");
循环执行10遍,把Action中保留一个,你看还能一样?
yehong_sky 2009-02-16
  • 打赏
  • 举报
回复
帮顶LZ...
awusoft 2009-02-16
  • 打赏
  • 举报
回复
经过我测试后发现maxActive在作怪.
OpenSessionInViewFilter 不是用来设置一个请求一个session的吗?在我请求一个Action的过程的时候,应该是一个线程吧.不管这个Action的方法进行多次查询,它都应该在同一个线程里啊.
我现在也是把事务设置在service(manager)了吧?
esena 2009-02-16
  • 打赏
  • 举报
回复
顺便说一下:
应该尽量避免数据库事务之外的多次数据库操作的方法,
这点可以通过代码技巧来达到,转移到事务中去

因为带来的直接问题就是数据库多次联接释放而产生的性能问题
这点很多时候会被忽略,也是很多时候难以查出的性能瓶颈
sqiong 2009-02-16
  • 打赏
  • 举报
回复
路过,等测试下在评价
esena 2009-02-16
  • 打赏
  • 举报
回复
你的spring事务配置的是Action的下层Manager层的吧,所以在Action中看来不是单事务的,
也就不能保证数据库session是单session了
在Action中进行多少次数据库操作就是多少次数据库联接

你可以把数据库操作转移到Action层以下试试
sccdry 2009-02-16
  • 打赏
  • 举报
回复
学习SSH框架中
HinanaiTenshi 2009-02-16
  • 打赏
  • 举报
回复
路过学习.

81,094

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧