系统单机部署,如果遇到请求卡的情况,造成了请求堆积,就极有可能造成重复提交的问题。解决重复提交问题的关键在于保证操作的原子性。
单机部署有多种解决方案,既可以利用数据库的原子性,又可以利用内存的原子性。
但是如果部署在多台机器上,依然会出现问题,因为请求卡话的,就很有可能多个重复请求分布在多台机器上,依然会造成重复提交的情况。
解决这一问题,可以利用redis 或者 memcached的cas模式。
memcached的单个命令是完全原子的,如果针对同一份数据同时发送了一个set命令和一个get命令,它们不会影响对方。它们将被串行化、先后执行。即使在多线程模式,所有的命令都是原子的。
废话不多说,上代码
@Service public class BindResubmitService { @Autowired private MemcachedHelper memcachedHelper; private static final Logger logger = LoggerFactory.getLogger(BindResubmitService.class); private final static int h2s=3600; public boolean bindResubmitMethod(Long interval,String key){ MemcachedClient client= memcachedHelper.getMemcachedClient(); Long newValue=new Date().getTime(); GetsResponse<Long> result; try { result = client.gets(key); if(null==result){ client.set(key, 24*h2s, newValue); return true; }else{ Long cas=result.getCas(); Long preValue=result.getValue(); if(interval==null){ return true; } if((newValue-preValue)<interval){ return false; } if(!client.cas(key, 24*h2s, newValue, cas)){ return false; } return true; } } catch (Exception e) { logger.error("防止重复提交运行异常,error:{}",e.getMessage()); return true; } } }