系統單機部署,如果遇到請求卡的情況,造成了請求堆積,就極有可能造成重復提交的問題。解決重復提交問題的關鍵在於保證操作的原子性。
單機部署有多種解決方案,既可以利用數據庫的原子性,又可以利用內存的原子性。
但是如果部署在多台機器上,依然會出現問題,因為請求卡話的,就很有可能多個重復請求分布在多台機器上,依然會造成重復提交的情況。
解決這一問題,可以利用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; } } }