RedisLock锁使用记录

1.RedisLock锁使用代码片段

@AutowiredRedisLockHelper 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);}}
  1. 代码片段中使用到的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;/*** @author edz*/
@Component
@Slf4j
public class RedisLockHelper {@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 加锁* @param targetId   targetId - 商品的唯一标志* @param timeStamp  当前时间+超时时间 也就是时间戳* @return*/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;}/*** 解锁* @param target* @param timeStamp*/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);}}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部