后端怎么防止重复提交?(常用的做法)
客户端的抖动,快速操作,网络通信或者服务器响应慢,造成服务器重复处理。防止重复提交,除了从前端控制,后台也需要控制。因为前端的限制不能解决彻底。接口实现,通常要求幂等性,保证多次重复提交只有一次有效。对于更新操作,达到幂等性很难。
常用后端防止重复提交方案
- token
访问请求到达服务器,服务器端生成token,分别保存在客户端和服务器。提交请求到达服务器,服务器端校验客户端带来的token与此时保存在服务器的token是否一致,如果一致,就继续操作,删除服务器的token。如果不一致,就不能继续操作,即这个请求是重复请求。
- 缓存
request进来,没有就先存在缓存中,继续操作业务,最后删除缓存或者缓存设置生命周期。如果存在,就直接对request进行验证,就不能继续操作业务。
- 索引
数据库中创建唯一索引,记录每次request请求。添加索引成功,就获取锁,继续操作,最后设置索引失效。添加索引失败,获取锁失败,不能继续操作。
- Redis的计数器
Redis的计数器是原子操作,不存储请求,又能提升QPS的峰值。每次request请求,若相同请求,计数器+1,否则新建id为key的计数器。如果>1,不能获取锁;如果=1,获取锁,操作,最后删除计数器(删除锁)。
- Post/Redirect/Get
提交(Post)后执行页面重定向,成功后转到提交成功页面(Get),整个流程才算结束。当刷新页面,或者浏览器前进和后退,都不会引起Post请求的重复提交。这里可以在head中设置control-cache,保存表单信息。这个方法依赖前端限制比较多。