当前位置:网站首页>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;
}
}
}
边栏推荐
- 将ABAP On-Premises系统连接到中央检查系统以进行自定义代码迁移
- 智能运维实战:银行业务流程及单笔交易追踪
- 【目标跟踪】|STARK
- Recommendation of data acquisition tools and detailed graphic process of data acquisition list
- 贝联珠贯加入龙蜥社区,共同促进碳中和
- Create employee data in SAP s/4hana by importing CSV
- 【显存优化】深度学习显存优化方法
- [Cloudera][ImpalaJDBCDriver](500164)Error initialized or created transport for authentication
- Microservice tracking SQL (support Gorm query tracking under isto control)
- 【STM32-USB-MSC问题求助】STM32F411CEU6 (WeAct)+w25q64+USB-MSC Flash用SPI2 读出容量只有520KB
猜你喜欢

Summary of point cloud reconstruction methods I (pcl-cgal)

Implementation of wechat web page subscription message

重回榜首的大众,ID依然乏力

S32K1xx 微控制器的硬件設計指南

Photoshop plug-in HDR (II) - script development PS plug-in

How to realize clock signal frequency division?

MySQL service is starting. MySQL service cannot be started. Solution

Tiantou village, Guankou Town, Xiamen special agricultural products Tiantou Village special agricultural products ant new village 7.1 answer

The solution to turn the newly created XML file into a common file in idea

Short Wei Lai grizzly, to "touch China" in the concept of stocks for a living?
随机推荐
Zhang Chi Consulting: household appliance enterprises use Six Sigma projects to reduce customers' unreasonable return cases
go-zero实战demo(一)
MySQL backup and restore single database and single table
如何写出好代码 - 防御式编程指南
Summary of empty string judgment in the project
Tableapi & SQL and MySQL data query of Flink
Skywalking 6.4 distributed link tracking usage notes
Guide de conception matérielle du microcontrôleur s32k1xx
Lean Six Sigma project counseling: centralized counseling and point-to-point counseling
Reading notes of top performance version 2 (V) -- file system monitoring
Can I choose to open an account on Great Wall Securities? Is it safe?
How to realize clock signal frequency division?
Tableapi & SQL and Kafka message insertion in Flink
[one day learning awk] conditions and cycles
微信网页订阅消息实现
[target tracking] | template update time context information (updatenet) "learning the model update for Siamese trackers"
A unifying review of deep and shallow anomaly detection
【300+精选大厂面试题持续分享】大数据运维尖刀面试题专栏(三)
STM32F4-TFT-SPI时序逻辑分析仪调试记录
Stm32f4-tft-spi timing logic analyzer commissioning record