日期:2014-05-18  浏览次数:20616 次

【100分,大牛、请进】非常棘手的问题,大家帮帮我吧
1,   页面A有一个按钮,点击他执行存储过程,由于数据量非常的大需要20分钟左右。
2,利用struts的Token机制来避免用户对这个按钮(也就是表单)的重复提交。
3,第一次按下了这个按钮,经过Token机制可以执行这个存储过程但是时间比较长,而且规定
执行完毕之后转到B这个页面提示用户存储过程执行成功。
4,在这20分钟期间,用户在一次点击这个按钮,由于有Token机制的保证,不会执行存储过程,但是问题来了。。。
虽然这次不执行存储过程,但是由于struts的action里面必须有个返回值,然后要跳转到一个页面上,由于这次时间比较短
所以跳转就会先响应这次的请求(而不是执行存储过程的那次,就是第一次)。这时后台还在执行存储过程,并且用户也看不到
B这个通知用户存储过程执行完毕的页面了,所以这个问题很棘手


我想一个解决办法,
5,第一次按钮可以按,按过之后就变灰,但是由于我采用的是frame框架,这个时候用户如果点击frame中别的节点在点击回来
这个执行存储过程的节点,就还是可以出现重复提交的问题,于是有转回问题到了1


老师,朋友,兄弟们,帮帮我的忙吧,我真的崩溃了,是在不知道应该怎么办了,救救我吧,祝大家中秋快乐,10.1快乐,天天
快乐,家庭幸福,身体健康,赚多多的钱,谢谢了啊。

------解决方案--------------------
要执行20分钟?人家客户还不疯啦
当点击提交后,将整个浏览器罩起来,不让客户做任何操作如何呢
------解决方案--------------------
以下建议仅供参与:
你可以在提交的时候,同时打开一个模态窗口,使关闭按钮失效。可以在模态窗口中显示相关信息,如正在执行XX.....
等存储过程执行完成后,用程序关闭模态窗口
------解决方案--------------------
根据你的情况我想到个比较适合你的方式
1.点击提交将一个值赋到session中。
2.在你的菜单页判断session值,如果是提交状态,则将超链接截断返回
------解决方案--------------------
如果使用Struts 2 非常简单,参看:
http://blog.csdn.net/struts2/archive/2007/08/09/1733765.aspx

如果使用Struts 1.X
可以仿照上述的思想:
A 发起页面
B 自刷新页面
C 结果页面

过程:
页面A点击之后程序执行,执行技术之后设置某个状态(Session或者数据库)
同时迁移到B页面,B页面一直刷新上述的状态,完成的状态下迁移C页面,否则迁移回B页面。

为了防止在B刷新的过程中客户点击这个Frame之外的其他按钮,可以使用JavaScript讲这个浏览器窗口锁定。


------解决方案--------------------
这些都是建议前端实现,我建议在后台实现,把你查询的类,里面的变量设置为静态变量,
服务器把每一次的请求生成一个线程,你让每一个线程共享一个类,这个方法也许可以.
每次开始查询时把变量设为false,在查询完成后再设为true.用到线程共享的方法,这是我的想法,不知是否可行,还是这个想法,我已经实现到了,只是,我用的是while循环,你可以用线程实现,省点资源
------解决方案--------------------
测试代码:
package com;

public class Run {

static boolean isRun=false;
static boolean second=false;
static int i;
public static int test()
{
while(isRun)//第二次点击就进入循环.
{
if(i%100000==0)System.out.println( "waiting.... "+i);
}
if(!second){//第二次点击不执行计算
second=true;
i=0;
isRun=true;
System.out.println( "staring....... ");
if(!isRun)
{
isRun=true;
}
for(int j=0;j <9900000;j++)
{
i++;
if(i%1000==0)System.out.println(i);
for(int k=0;k <399;k++)
{
}

}
isRun=false;//计算完毕,设置标志isRun=false;
}
return i;
}
}
在action获取i后把second设置为false,Run.second=false
------解决方案--------------------
像在http://community.csdn.net/Expert/topic/5771/5771611.xml?temp=.443432
中提到的,使用临时表的话,时间开销减小之后多重提交的矛盾就不再那么尖锐了。
你的系统应该是企业内部使用的吧,在企业内部的话,画面操作的安全、性能要求可以
适当降低,并且可以加上浏览器功能键禁用等一般在www上不用的处理。

不管是一天、一周、一月、一年执行一次的操作,用批处理+临时表的策略都是可行的。
实际上,大多数项目都是这么做的。

不过,多重提交确实是一个很值得研究的课题。