最近在练兵的时候碰到这个问题,在网上搜罗了一大遍,碰到这个问题的网友还真不少,在此做个备忘,
解决办法就是将所有全局变量取消,全部移入至每个业务方法内,这样就没问题啦。因此若出现此异常就一定
也分析一下出现这种异常的原因。
我的问题出现在Action中,我用的Action类型为DispatchAction,DispatchAction的特点就是通过配
置Action标签的parameter为method,然后在Action中直接定义多个业务方法,不同业务调用的是同一个
Action,只要加一个method的参数(参数值即为此业务方法在Action中的方法名)即可,调用的URL类似为:
**Action.do?method=setManageRoles,关于DispatchAction我就不多讲了,不清楚的可以参考Struts的
相关书籍和资料。
以下是我报异常的代码:
package struts.action;
import manage.UserManage;
import ..........
public class RolesModifyAction extends DispatchAction {
//全局变量
UserManage um = new UserManage();
RoleDao dao = new RoleDao();
String page = "";
// 业务方法一
public ActionForward setManageRoles(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
for (int j = 0; j < mbrand.length; j++) {
UserRole userrole = um.getUserRoleByUserName(mbrand[j]);
userrole.setRoleid(1);
dao.saveOrUpdate(userrole);
.........
}
return mapping.findForward(page);
}
public ActionForward setAgentRoles(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
.........
return mapping.findForward(page);
}
public ActionForward setNormalRoles(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
.........
return mapping.findForward(page);
}
以上代码为一个设置用户权限的Action,包含三个业务方法,在Action的开头我定义了这三个业务方法
共用的几个全局变量,这样看也没什么不妥,并且在执行时,第一次总能执行成功,但接着执行第二次的时候
就会抛出异常。尝试调试了很多次,但都未能解决,最后只有请同事帮忙了,同事一看就指出了死结:在
Ation中要避免定义全局变量,要定义都只能定义只读类型的,如常量,因为一个请求到达Action后即实例化
这些变量,并只实例化一次,这样以上代码的其它业务方法调用时将不会再实例化。
总结:
抛这个异常主要原因是在进行数据库操作时获取不到可用的连接,也就是说session已经关闭了。上面的
代码在执行第一次后(dao.saveOrUpdate(userrole);)已将session关闭了,注:我是利用过滤器控制事务的
提交与session的关闭的,每执行完一次请求,过滤器自动提交事务,然后关闭session。
解决办法就是将所有全局变量取消,全部移入至每个业务方法内,这样就没问题啦。因此若出现此异常就一定
是某段操作数据库的代码出现问题了,这段代码将数据库连接提前关闭了,只要揪出这段代码,再结合你的
相关业务逻辑调整就可解决了。