1.RedisLock锁使用代码片段
@Autowired
RedisLockHelper redisLock;
// 可以自定锁键
String lockKey = "simCard:"+tPhoneCardApply.getPhoneNum();
long timeMillis = System.currentTimeMillis();
// 定义锁多长时间
String timeStamp = String.valueOf(timeMillis + 60 * 5 * 1000);
boolean lock = redisLock.lock(lockKey,timeStamp);
try{
if(lock){
......需要执行的代码
}
}finally {
try {
redisLock.unlock(lockKey, timeStamp);
} catch (Exception e) {
e.printStackTrace();
logger.error("释放分布式锁失败! ", e);
}
}
- 代码片段中使用到的redisLock类
package com.huatek.frame.core.context;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RedisLockHelper {
@Autowired
private StringRedisTemplate stringRedisTemplate;
public boolean lock(String targetId,String timeStamp){
if(stringRedisTemplate.opsForValue().setIfAbsent(targetId,timeStamp)){
// 对应setnx命令,可以成功设置,也就是key不存在
return true;
}
// 判断锁超时 - 防止原来的操作异常,没有运行解锁操作 防止死锁
String currentLock = stringRedisTemplate.opsForValue().get(targetId);
// 如果锁过期 currentLock不为空且小于当前时间
if(!StringUtil.isNullOrEmpty(currentLock) && Long.parseLong(currentLock) < System.currentTimeMillis()){
// 获取上一个锁的时间value 对应getset,如果lock存在
String preLock =stringRedisTemplate.opsForValue().getAndSet(targetId,timeStamp);
// 假设两个线程同时进来这里,因为key被占用了,而且锁过期了。获取的值currentLock=A(get取的旧的值肯定是一样的),两个线程的timeStamp都是B,key都是K.锁时间已经过期了。
// 而这里面的getAndSet一次只会一个执行,也就是一个执行之后,上一个的timeStamp已经变成了B。只有一个线程获取的上一个值会是A,另一个线程拿到的值是B。
if(!StringUtil.isNullOrEmpty(preLock) && preLock.equals(currentLock) ){
// preLock不为空且preLock等于currentLock,也就是校验是不是上个对应的商品时间戳,也是防止并发
return true;
}
}
return false;
}
public void unlock(String target,String timeStamp){
try {
String currentValue = stringRedisTemplate.opsForValue().get(target);
if(!StringUtil.isNullOrEmpty(currentValue) && currentValue.equals(timeStamp) ){
// 删除锁状态
stringRedisTemplate.opsForValue().getOperations().delete(target);
}
} catch (Exception e) {
log.error("警报!警报!警报!解锁异常{}",e);
}
}
}



