lua脚本
if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end
测试代码:
导入依赖
配置redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.7.5</version>
</dependency>
spring:
application:
name: springdataredis_demo
#Redis相关配置
redis:
host: localhost
port: 6379
#password: 123456
database: 0 #操作的是0号数据库
jedis:
#Redis连接池配置
pool:
max-active: 8 #最大连接数
max-wait: 1ms #连接池最大阻塞等待时间
max-idle: 4 #连接池中的最大空闲连接
min-idle: 0 #连接池中的最小空闲连接
package com.example.lua;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.time.Duration;
import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/api/v1")
public class CouponController {
@Autowired
private StringRedisTemplate redisTemplate;
@GetMapping("add")
public String saveGroup(@RequestParam(value="coupon_id",required = true) int couponId) {
// 防止其他线程误删
String uuid = UUID.randomUUID().toString();
String lockKey = "lock:coupon:"+couponId;
lock(couponId,uuid,lockKey);
return "success";
}
private void lock(int couponId, String uuid, String lockKey) {
// Lua脚本
String script = "if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
Boolean nativeLock = redisTemplate.opsForValue().setIfAbsent(lockKey,uuid, Duration.ofSeconds(30));
System.out.println(uuid+"加锁状态:"+nativeLock);
if(Boolean.TRUE.equals(nativeLock)) {
// 加锁成功
try {
// 做相应业务逻辑
TimeUnit.SECONDS.sleep(10L);
}catch (Exception e) {
}finally {
// 解锁
Long result = redisTemplate.execute(new DefaultRedisScript<>(script,Long.class),
Collections.singletonList(lockKey),uuid);
System.out.println(uuid+":解锁状态:"+result);
}
}else {
// 自旋操作
try{
System.out.println("加锁失败,随眠5秒,进行自旋");
TimeUnit.MILLISECONDS.sleep(5000);
}catch (Exception e) {
}
lock(couponId,uuid,lockKey);
}
}
}