防止表单重复提交订单

来源:互联网 发布:艾泽拉斯数据库 人口 编辑:程序博客网 时间:2024/05/22 01:31

在分布式项目维护中遇到了表单重复提交的问题

第一次出现这个bug时我用了最简单的方式,就是在前台js中控制提交按钮,防止重复点击如下这种方式,依然没有解决问题。

var btnFlag = true;$("#createOrder").click(function(){     if(btnFlag){btnFlag = false;ajax_post(url,param,'json',function(data){//xxxxxx});}    });


第二次  我用上了token ,原理是在jsp页面加载时在session中放入一个时间取到毫秒,再一块hidden 中赋值用ajax传值到后台,进行对比值,如果两值一样,就让提交。
如下,并且,把dubbo 的配置也改了,怕是因为服务多次调用出现的原因,又失败了。

 <%             long token=System.currentTimeMillis();    //产生时间戳的token              session.setAttribute("token",token);          %>  <input type="hidden" value="<%=token %>" name="Reqtoken" id="Reqtoken"/>   <!-- 作为hidden提交 -->

dubbo 配置

<dubbo:reference id="business.IOrder" interface="com.ailk.helios.center.business.service.IOrder"><dubbo:method name="createOrderAndSubmit" retries="0"  timeout="50000"/>



这回好好分析生产上打出来的日志,发现有从前台传值的log,出现了三次,说明不是dubbo服务的原因,问题出现的时间是间隔2毫秒,客户用的浏览器是UC,测试没有复现。
这个问题就是出现项目本身了,找来了jmeter做后台压力测试,出现了多次请求多次提交的问题(也是好好学习了一下工具呀,也挺有收获的)。本身项目用的是公司自己写的servlet框架,项目中也用了aop,所以在网上找springmvc+token的拦截器方法想进行拦截。放在项目中拦截器竟然不起作用,真是想哭。就想着要不写一个filter吧,因为项目中有很多自己写的filter可以用。但是老大提出了一个方式,加同步块吧。没错synchronized  就是它,在代码中小部分的加上如下,报着试试的心态做了jmeter,用了三个浏览器同时多线程测试,过了。开心呀!

String token = request.getParameter("Reqtoken");// 获取表单上面的时间戳T1          HttpSession session=request.getSession(false);          String tokenInSession = "";        synchronized(session){       tokenInSession  =  ""+session.getAttribute("token");        session.removeAttribute("token");         }


没有骄傲,怕影响项目,又做了一个防止一个用户阻塞,影响其它用户提交的测试如下,也通过了,三个用户,两个提交正常,一个在阻塞中。。
又做了一个测试,提交订单阻塞中的用户可不可用其它功能,可以用其他功能。ok.就先这样子。

  synchronized(session){       tokenInSession  =  ""+session.getAttribute("token");        session.removeAttribute("token");        if(session.getId().equals("4A8787C63C11A8D78A850BEEAFC0A87C") ){        while(true){        log.info("【阻塞中=================================】【此用户的session= "+session+"\n session.getId()="+session.getId());        }       }         }


总结:
       我知道这样子解决的方法是不太好,但是也是没有办法的事了,首先没有找到具体的bug原因,人手点击的速度不可能以毫秒记,所以这不科学呀。其次,测试的小伙伴们测试了不知道多少回也没有出现bug.开始分析为网络原因。唉!谁知道呢,总有很多事情无法解释。
如果再有这种事情,struts2 框架一定要优先考虑token 方式解决。springmvc框架要优先考虑拦截器+token的形式。网上也有很多教程。但以上也可以,是没有办法的办法啦。

0 0
原创粉丝点击