网络延迟,用户连续点击导致后台重复执行一条数据,后台怎么防止?

猫婶陛下


这是一个典型的防止重复提交的问题!实际场景中比如有重复扣款,重复购买的问题!

怎么设计能防止重复提交呢?我们主要有以下操作:

①,前端:点击提交的按钮在点击过后置灰,在一段时间之内不让重复提交!

优点:最省事,提高并发能力的方式!

缺点:页面刷新等情况js失效,前端容易被篡改!



②,后端:

1,加锁:对提交的id进行加锁操作,在一定的时间范围内同样的id只能通过一次!

如果是分布式服务,需要借助redis等来加分布式锁,不然多个服务中锁不能互斥!

2,幂等:保证接口幂等,先查询,如果记录不存在再新增,如果存在就返回查询结果!

缺点:高并发环境没法保证幂等性!

③,数据库:如果是新增,可加唯一字段,在保存的时候如果唯一字段重复会抛出异常,使用insert ignore语句,做判断!



如果是修改,可以使用乐观锁sql,保证版本version满足的时候再执行sql!如下例就是乐观锁机制:

update table_test set name=name1,version=version+1 where id=id1 and version=2;

我实际工作中就用到上面几种方法,如果还有更为合适有效的方法,请补充。。笔者一直在持续的分享JAVA开发技术,其中不乏百赞好文,有需要的朋友可以关注下。。


此生唯一


这样的问题在实际场景中会经常出现,主要解决方案在于如何防止重复提交而引起的重复数据执行的问题。
对于这个问题,一般会从两方面同时配合解决。

首先,前端平台就应该考虑到快速点击导致的重复提交问题, 具体的办法有:“防抖”或直接将交互按钮置灰,这样做可以很方便的阻止了重复提交的问题,但如果页面刷新,方法又会失效,况且只在前端做是很不安全,很不可靠的。

第二点,最重要的就是在后端做拦截:如果你是一名Java工程师的话,给你几条建议:

对于数据库,可以通过增加唯一字段来确定,如果在新增的时候,唯一字段重复了,则抛出异常;如果是修改,利用乐观锁的方法实现.保证version满足的时候在执行,这样就是可以的了。

update table _test set name = name1,version = version+1 where id =1 and verison =2

还有高级的方法:幂等,保证接口幂等,先查询,如果记录不存在再新增,如果存在就返回查询结果。

具体如何使用这些方法需要根据实际问题及项目状况来选择。


一郭鲜


这是一个很典型的节流问题

办法一:简单的办法可以在点击的时候给按钮置为不可点击状态,等请求回来后再设置为可点击

办法二:在内存中记录一个pending状态记录当前请求是否是发送中,如果是发送中就不重复发了,待请求回调回来后重置该状态

办法三:如果你是用的xhr发送的ajax请求,可以设置为发送同步请求

还是需要根据你所使用的技术栈来决定使用什么办法

关于节流的概念可以参考 高级程序设计



古士日1818188


乐观锁,还有session放操作id,如果有就允许点击,如果没有就不允许