当前位置:网站首页>How to implement a distributed lock with redis
How to implement a distributed lock with redis
2022-06-23 11:14:00 【InfoQ】
Scene simulation

@RestController
public class SkillController {
@Autowired
private RedisTemplate redisTemplate;
// Seckill interface
@RequestMapping("/deduct_stock")
public String deductStock() {
// Lock
synchronized (this) {
int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock").toString());
if (stock > 0) {
// stock -1
int realStock = stock - 1;
// Deducting the inventory
redisTemplate.opsForValue().set("stock", realStock + "");
System.out.println(" Deduction succeeded , Surplus stock :" + realStock);
} else {
System.out.println(" Deduction failed , Insufficient inventory ");
}
}
return "8080";
}
}
@RestController
public class SkillController {
@Autowired
private RedisTemplate redisTemplate;
// Seckill interface
@RequestMapping("/deduct_stock")
public String deductStock() {
// Lock
synchronized (this) {
int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock").toString());
if (stock > 0) {
// stock -1
int realStock = stock - 1;
// Deducting the inventory
redisTemplate.opsForValue().set("stock", realStock + "");
System.out.println(" Deduction succeeded , Surplus stock :" + realStock);
} else {
System.out.println(" Deduction failed , Insufficient inventory ");
}
}
return "8090";
}
}


JVM lock



Redis SETNX
@RestController
public class SkillController {
@Autowired
private RedisTemplate redisTemplate;
@RequestMapping("/deduct_stock")
public String deductStock() {
// goods ID, In the specific application, the request should be passed in
String lockKey = "lock:product_01";
// SETNX Lock
Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, "product");
// If false It means that the lock exists , Go straight back to
if (!result) {
// Simulate the return service
return " The system is busy ";
}
int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock").toString());
if (stock > 0) {
// stock -1
int realStock = stock - 1;
// Deducting the inventory Simulate more business operations
redisTemplate.opsForValue().set("stock", realStock + "");
System.out.println(" Deduction succeeded , Surplus stock :" + realStock);
} else {
System.out.println(" Deduction failed , Insufficient inventory ");
}
// The lock needs to be released after locking
redisTemplate.delete(lockKey);
return "8080";
}
}try catchtry finally
Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, "product");
redisTemplate.expire(lockKey, 10, TimeUnit.SECONDS);Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, "product", 10, TimeUnit.SECONDS);
Redisson
@RestController
public class RedissonController {
@Autowired
private Redisson redisson;
@Autowired
private RedisTemplate redisTemplate;
@RequestMapping("/deduct_stock1")
public String deductStock() {
// goods ID, In the specific application, the request should be passed in
String lockKey = "lock:product_01";
// Get the lock
RLock lock = redisson.getLock(lockKey);
// Lock
lock.lock();
try {
int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock").toString());
if (stock > 0) {
// stock -1
int realStock = stock - 1;
// Deducting the inventory
redisTemplate.opsForValue().set("stock", realStock + "");
System.out.println(" Deduction succeeded , Surplus stock :" + realStock);
} else {
System.out.println(" Deduction failed , Insufficient inventory ");
}
} finally {
// Release the lock
lock.unlock();
}
return "8080";
}
}

lualuaRedissonLock.lock()--->lockInterruptibly()--->tryAcquire()--->tryLockInnerAsync()tryLockInnerAsync()<T> RFuture<T> tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {
internalLockLeaseTime = unit.toMillis(leaseTime);
return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, command,
// If the lock doesn't exist , Through hset Set its value , And set expiration time
"if (redis.call('exists', KEYS[1]) == 0) then " +
"redis.call('hset', KEYS[1], ARGV[2], 1); " +
"redis.call('pexpire', KEYS[1], ARGV[1]); " +
"return nil; " +
"end; " +
// If the lock already exists , It is the current thread , Through hincrby Incrementing the value 1, That is, the re-entry of the lock
"if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
"redis.call('hincrby', KEYS[1], ARGV[2], 1); " +
"redis.call('pexpire', KEYS[1], ARGV[1]); " +
"return nil; " +
"end; " +
// If the lock already exists , Not the current thread , The expiration time is returned ttl
"return redis.call('pttl', KEYS[1]);",
Collections.<Object>singletonList(getName()), internalLockLeaseTime, getLockName(threadId));
}RedissonLock.lock()--->lockInterruptibly()--->tryAcquire()--->scheduleExpirationRenewal()scheduleExpirationRenewal()lua// getName() Is the name of the current lock
RFuture<Boolean> future = commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,
// Judge this lock getName() Whether in redis in , If there is one, go ahead pexpire delay Default 30s
"if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
"redis.call('pexpire', KEYS[1], ARGV[1]); " +
"return 1; " +
"end; " +
"return 0;",
Collections.<Object>singletonList(getName()), internalLockLeaseTime, getLockName(threadId));
getName()pexpirelockWatchdogTimeout=30slockWatchdogTimeout/3=10s边栏推荐
- 不止于观测|阿里云可观测套件正式发布
- 1154. day of the year
- Interview Manual of social recruitment Tencent high P (Senior Product Manager)
- Economic common sense
- Install the typescript environment and enable vscode to automatically monitor the compiled TS file as a JS file
- Torch weight to mindspore
- File has not been synchronized when NFS is mounted
- Whether Changan Lumin has the ability to become a broken product in the micro electricity market
- Explain in detail the method of judging the size end
- Noi OJ 1.4 01: positive and negative C language
猜你喜欢

如何用 Redis 实现一个分布式锁

Design and implementation of stm32f103zet6 single chip microcomputer dual serial port mutual sending program

最简单DIY基于STM32的远程控制电脑系统①(电容触摸+按键控制)

连番承压之后,苹果或将大幅提高iPhone14的售价

今天14:00 | 12位一作华人学者开启 ICLR 2022

Why does the pointer not change the corresponding value as a formal parameter

C语言结构体字节对齐问题

Step by step introduction to sqlsugar based development framework (9) -- Realizing field permission control with WinForm control

A child process is created in the program, and then the parent and child processes run independently. The parent process reads lowercase letters on the standard input device and writes them to the pip

Unity technical manual - limit velocity over lifetime sub module and inherit velocity sub module
随机推荐
A child process is created in the program, and then the parent and child processes run independently. The parent process reads lowercase letters on the standard input device and writes them to the pip
Installation and use of binabsinspector, an open source binary file static vulnerability analysis tool
塔米狗 | 投资人类型分析以及企业投资类型分析
【ML】QuantileRegressor
开发增效利器—2022年VsCode插件分享
“互联网+”大赛命题火热对接中 | 一图读懂百度38道命题
Simplest DIY mpu6050 gyroscope attitude control actuator program based on stm32f407 Explorer development board
力扣 1319. 连通网络的操作次数
SPI与IIC异同
Solve the problem of invalid audio autoplay
实现常用C语言字符串处理函数
单向链表实现--计数
The simplest DIY pca9685 steering gear control program based on the integration of upper and lower computers of C # and 51 single chip microcomputer
圖片存儲--引用
Android security / reverse interview questions
php 正则表达式
vector的介绍及使用
ESP32-CAM、ESP8266、WIFI、蓝牙、单片机、热点创建嵌入式DNS服务器
长安LUMIN是否有能力成为微电市场的破局产品
Tensorrt notes (IV) reasoning segmentation model