(高并发)防止重复点击,屏蔽多次无效请求的解…
2019-03-06 07:15:38来源:博客园 阅读 ()
一、问题描述:
单应用切换至分布式,优惠劵被同一时间同一优惠劵领取多张,比如使用模拟器1s内请求1000次,可能被领取100张。
以前插入前先查询是否存在,无法有效解决,还是会被撸羊毛。
二、解决方法:
1.app前端增加控制,(比如按钮点击后失效);
2.利用数据库层的事务处理,比如:插入的同时查询是否存在,利用数据库自身的事务管理,同一sql实现
insert into buyer_collect(buyer_id,goods_id,create_time) select #{userId},#{goodsId},now() from dual where not exists(select 1 from buyer_collect where buyer_id = #{userId} and goods_id = #{goodsId})
3.redis互斥锁(个人推荐,复用性好,稳定性好)
如果框架还未整合redis请自行查阅处理,这边直接上解决方案:引入jar包,本人使用2.9
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
利用jedis类的set方法特性
nxxx的值只能取NX或者XX,如果取NX,则只有当key不存在是才进行set,如果取XX,则只有当key已经存在时才进行set
expx的值只能取EX或者PX,代表数据过期时间的单位,EX代表秒,PX代表毫秒。
time 过期时间,单位是expx所代表的单位。
public String set(String key, String value, String nxxx, String expx, int time) { this.checkIsInMultiOrPipeline(); this.client.set(key, value, nxxx, expx, time); return this.client.getStatusCodeReply(); }
编写公共方法,可根据自己的实际情况自行改造,本用例来源于网络,较为成熟稳定(亲测可行)
1 private static final String LOCK_SUCCESS = "OK"; 2 private static final String SET_IF_NOT_EXIST = "NX"; 3 private static final String SET_WITH_EXPIRE_TIME = "EX"; 4 5 /** 6 * 获取分布式锁 7 * @param lockKey 锁 8 * @param requestId 请求标识 9 * @param expireTime 超期时间 10 * @return 是否获取成功 11 */ 12 public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) { 13 Jedis jedis = null; 14 try { 15 jedis = getJedis();
16 String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); 17 if (LOCK_SUCCESS.equals(result)) { 18 return true; 19 } 20 return false; 21 } finally { 22 returnResource(jedis); 23 } 24 }
//Redis缓存 5S内重复请求无效 Boolean result = null; String key = "项目名称+功能模块" + userId + couponId; String requestId = UUID.randomUUID().toString(); try { //获取分布式锁 result = redisCacheService.tryGetDistributedLock(key, requestId, 5); }catch (Exception e){ return new JsonResult(JsonResultCode.FAILURE,"连接redis取数异常",""); } if(!result){ return new JsonResult(JsonResultCode.FAILURE,"请勿频繁点击!",""); }
附上使用的一小段代码,希望能秒懂解决实际问题
userId :用户id
couponId :优惠劵id
项目名称+功能模块:根据自己项目命名
结合自己项目框架自行修改,一次编写,复用性好。有效解决项目中类型的问题
原文链接:https://www.cnblogs.com/180308-new-file/p/10479114.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 那些面试官必问的JAVA多线程和并发面试题及回答 2020-05-28
- 【JavaSE】多线程与并发编程(总结) 2020-05-25
- Java并发编程volatile关键字 2020-05-24
- Java并发学习笔记 线程篇 2020-05-24
- 还搞不定Java多线程和并发编程面试题?你可能需要这一份书单 2020-05-18
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash