当前位置:网站首页>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边栏推荐
- Win10 Microsoft input method (Microsoft Pinyin) does not display the word selection column (unable to select words) solution
- More than observation | Alibaba cloud observable suite officially released
- 智慧园区效果不满意?请收下ThingJS这份秘籍
- Deveco device tool helps openharmony device development
- Stockage d'images - référence
- Not satisfied with the effect of the smart park? Please accept this secret script of thingjs
- Tensorrt notes (IV) reasoning segmentation model
- 塔米狗 | 投资人类型分析以及企业投资类型分析
- Noi OJ 1.2 06: round floating point numbers to zero
- 中国十大券商有哪些?手机开户安全么?
猜你喜欢

Experience of using thread pool in project

技术创造价值,手把手教你薅羊毛篇

智慧园区效果不满意?请收下ThingJS这份秘籍

ESP32-CAM无线监控智能网关的设计与实现

从0到1,IDE如何提升端侧研发效率?| DX研发模式

经济小常识

The simplest DIY actuator controller based on 51 single chip microcomputer

Not satisfied with the effect of the smart park? Please accept this secret script of thingjs

R and rstudio download and install detailed steps

Esp32-cam, esp8266, WiFi, Bluetooth, MCU, hotspot create embedded DNS server
随机推荐
torch权重转mindspore
UWA new | real person real machine test new overseas model zone
list的深度剖析及模拟实现
Explain in detail the method of judging the size end
Why should poll/select use Nonblock when opening
安卓安全/逆向面试题
Large homework collection
What are the top ten securities companies in China? Is it safe to open a mobile account?
Analysis of LinkedList source code
不止于观测|阿里云可观测套件正式发布
5 login failures, limiting login practice
DevEco Device Tool 助力OpenHarmony设备开发
The simplest DIY actuator cluster control program based on 51 single chip microcomputer, pca9685, IIC and PTZ
Win10 Microsoft input method (Microsoft Pinyin) does not display the word selection column (unable to select words) solution
Noi OJ 1.4 05: integer size comparison C language
Why does the pointer not change the corresponding value as a formal parameter
深潜Kotlin协程(十四):共享状态的问题
Rancher 2.6 全新 Monitoring 快速入门
Share a mobile game script source code
NOI OJ 1.2 10:Hello, World! Size of C language