当前位置:网站首页>Redis seckill demo
Redis seckill demo
2022-07-01 15:35:00 【y_ w_ x_ k】
Scheme 1 : Method plus synchronized that will do , Thread safety scheme , But the efficiency of execution is low , Not suitable for large concurrent occasions
Option two : Use optimistic lock
controller:
@RestController
public class SecondKill {
@Autowired
SecondKillSev secondKillSev;
@RequestMapping(value = "/buy",method = RequestMethod.POST)
public Mes buy(@RequestParam("proid") String proid){
String usedId=new Random().nextInt(1000)+"";
Mes mes = secondKillSev.doSecondKill(usedId, proid);
return mes;
}
}service:
@Service
public class SecondKillSev {
Mes message;
public SecondKillSev(){
}
@Autowired
StringRedisTemplate stringRedisTemplate;
/**
* Execute seckill
* Scheme 1 :synchronized, Thread safety , But the efficiency of execution is low , Not suitable for large concurrent occasions
* Option two : Monitor transactions with optimistic locks
*/
public Mes doSecondKill(String uid, String proid){
//1. Judge uid and proid Non empty
if(uid==null || proid==null){
return Mes.getMes("400","uid and proid Can't be empty ");
}
//2. Connect redis
ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
//3. Splicing key, stock key, Successful user key
String kcKey="kcKey:"+proid;
String userKey="userKey:"+proid;
// Optimistic lock solves oversold problem
//stringRedisTemplate The default is not to open things
stringRedisTemplate.setEnableTransactionSupport(true);
List<Object> txResults = stringRedisTemplate.execute(new SessionCallback<List<Object>>() {
public List<Object> execute(RedisOperations operations) throws DataAccessException {
// Monitor inventory
operations.watch(kcKey);
//4. Get inventory , If the inventory is null, The second kill has not yet started
String kc=ops.get(kcKey);
if(kc==null){
message= Mes.getMes("400"," The stock is null, The second kill hasn't started yet ");
return null;
}
//5. Judge whether the user repeats the second kill
if(operations.opsForSet().isMember(userKey, uid)){
message=Mes.getMes("400"," You can't repeat the second kill ");
return null;
}
//6. Judge the quantity of goods , If the quantity is less than 1, Then the second kill is over
if(Integer.parseInt(kc)<=0){
message=Mes.getMes("400"," The second kill is over ");
return null;
}
//7. Second kill process , stock -1, Successful user added to manifest
// With a transaction
operations.multi();
operations.opsForValue().decrement(kcKey);
operations.opsForSet().add(userKey,uid);
List exec = operations.exec();
if(exec==null || exec.size()==0){
message=Mes.getMes("400"," Seckill failure ");
return null;
}else{
return exec;
}
}
});
if(txResults==null ||txResults.size()==0){
return message;
}
return Mes.getMes("200"," Seckill success ");
}
}
But this scheme also has a disadvantage , That is, if the quantity of goods is 500, But the number of threads is 1000, That is, when the number of visits is not very large , There will be the problem that the inventory is not sold out , That is, inventory leftover problems , So it can be used lua Script to solve ;
Option three :lua Script
local userid=KEYS[1];
local prodid=KEYS[2];
local qtkey="sk:"..prodid..":qt";
local userskey="sk:"..prodid..":user";
local userExists=redis.call("sismember",userskey,userid);
if tonumber(userExists)==1 then
return 2;
end
local num=redis.call("get",qtkey);
if tonumber(num)<=0 then
return 0;
else
redis.call("decr",qtkey);
redis.call("sadd",userskey,userid);
end
return 1
Code implementation :
@Service
public class SeckillByScript {
static String secKillScript1 = "local userid=KEYS[1];\n" +
"local prodid=KEYS[2];\n" +
"local qtkey=\"sk:\"..prodid..\":qt\";\n" +
"local userskey=\"sk:\"..prodid..\":user\";\n" +
"local userExists=redis.call(\"sismember\",userskey,userid);" +
"if tonumber(userExists)==1 then\n" +
" return 2;\n" +
"end\n" +
"local num=redis.call(\"get\",qtkey);\n" +
"if tonumber(num)<=0 then\n" +
" return 0;\n" +
"else\n" +
" redis.call(\"decr\",qtkey);\n" +
" redis.call(\"sadd\",userskey,userid);\n" +
" end\n" +
" return 1";
public boolean doSecKill(String userid, String prodid) {
JedisPool jedisPool = JedisPoolUtil.getJedisPool();
Jedis jedis = jedisPool.getResource();
String sha1 = jedis.scriptLoad(secKillScript1);
Object result = jedis.evalsha(sha1, 2, userid, prodid);
String reString = String.valueOf(result);
if ("0".equals(reString)) {
System.out.println(" Empty !");
return false;
} else if ("1".equals(reString)) {
System.out.println(" Panic buying ");
return true;
} else if ("2".equals(reString)) {
System.out.println(" The user has robbed !");
return false;
} else {
System.out.println(" Panic buying exception ");
return false;
}
}
}
边栏推荐
- Task.Run(), Task.Factory.StartNew() 和 New Task() 的行为不一致分析
- Zhang Chi Consulting: household appliance enterprises use Six Sigma projects to reduce customers' unreasonable return cases
- Junda technology indoor air environment monitoring terminal PM2.5, temperature and humidity TVOC and other multi parameter monitoring
- SAP S/4HANA: 一条代码线,许多种选择
- 点云重建方法汇总一(PCL-CGAL)
- MySQL审计插件介绍
- k8s部署redis哨兵的实现
- GaussDB(for MySQL) :Partial Result Cache,通过缓存中间结果对算子进行加速
- 选择在长城证券上炒股开户可以吗?安全吗?
- swiper 轮播图,最后一张图与第一张图无缝衔接
猜你喜欢

Junda technology - wechat cloud monitoring scheme for multiple precision air conditioners
![Stm32f411 SPI2 output error, pb15 has no pulse debugging record [finally, pb15 and pb14 were found to be short circuited]](/img/ea/8c9f716717bc08f2e563c577738ec8.png)
Stm32f411 SPI2 output error, pb15 has no pulse debugging record [finally, pb15 and pb14 were found to be short circuited]
![[target tracking] | template update time context information (updatenet)](/img/53/0a8b2135fa4903f30e4573256c393a.png)
[target tracking] | template update time context information (updatenet) "learning the model update for Siamese trackers"
![[advanced ROS] lesson 5 TF coordinate transformation in ROS](/img/4d/ae7d477bf6928005e16f046d461dcb.png)
[advanced ROS] lesson 5 TF coordinate transformation in ROS
Sort out the four commonly used sorting functions in SQL

【显存优化】深度学习显存优化方法

如何实现时钟信号分频?

Lean Six Sigma project counseling: centralized counseling and point-to-point counseling

MySQL backup and restore single database and single table

《QT+PCL第九章》点云重建系列2
随机推荐
Junda technology - wechat cloud monitoring scheme for multiple precision air conditioners
[antenna] [3] some shortcut keys of CST
Tableapi & SQL and MySQL data query of Flink
Reading notes of top performance version 2 (V) -- file system monitoring
Task.Run(), Task.Factory.StartNew() 和 New Task() 的行为不一致分析
点云重建方法汇总一(PCL-CGAL)
JS中箭头函数和普通函数的区别
Flink 系例 之 TableAPI & SQL 与 Kafka 消息获取
STM32F411 SPI2输出错误,PB15无脉冲调试记录【最后发现PB15与PB14短路】
Stm32f411 SPI2 output error, pb15 has no pulse debugging record [finally, pb15 and pb14 were found to be short circuited]
Introduction to MySQL audit plug-in
An intrusion detection model
OpenSSL client programming: SSL session failure caused by an insignificant function
微信小程序01-底部导航栏设置
微信公众号订阅消息 wx-open-subscribe 的实现及闭坑指南
微信网页订阅消息实现
Deep operator overloading (2)
S32K1xx 微控制器的硬件设计指南
Connect the ABAP on premises system to the central inspection system for custom code migration
榨汁机UL982测试项目有哪些