简易的Redis分布式事务锁

编程

0.背景

  在物联网微服务时代,面对源源不断的数据,难免会遇到需要一把分布式事务" title="分布式事务">分布式事务锁的情况,今天,我们学习一下Redis分布式事务锁。

1.用于上锁的类

RedisLock.java

public class RedisLock {

private static final Logger log = LoggerFactory.getLogger(RedisLock.class);

@Resource(name = "deviceStringRedisTemplate")

private StringRedisTemplate redisTemplate;

/**

* redis键过期时间,毫秒为单位

*/

private static final long EXPIRE = 5 * 1000L;

/**

* 尝试获取锁的超时时间,不能一直尝试获取锁,空耗资源。

*/

private static final long TIMEOUT = 10 * 1000L;

public boolean lock(String key, String value) {

log.info("尝试获取锁 kye:{},value:{}", key, value);

//请求锁时间

long requestTime = System.currentTimeMillis();

while (true) {

//等待锁时间

long watiTime = System.currentTimeMillis() - requestTime;

//如果等待锁时间超过10s,加锁失败

if (watiTime > TIMEOUT) {

log.info("等待锁超时 kye:{},value:{}", key, value);

return false;

}

if (redisTemplate.opsForValue().setIfAbsent(key, String.valueOf(System.currentTimeMillis()))) {

//获取锁成功

log.info("获取锁成功 kye:{},value:{}", key, value);

//设置超时时间,防止解锁失败,导致死锁

redisTemplate.expire(key, EXPIRE, TimeUnit.MILLISECONDS);

return true;

}

String valueTime = redisTemplate.opsForValue().get(key);

if (!StringUtils.isEmpty(valueTime) && System.currentTimeMillis() - Long.parseLong(valueTime) > EXPIRE) {

//加锁时间超过过期时间,删除key,防止死锁

log.info("锁超时, key:{}, value:{}", key, value);

try {

redisTemplate.opsForValue().getOperations().delete(key);

} catch (Exception e) {

log.info("删除锁异常 key:{}, value:{}", key, value);

e.printStackTrace();

}

return false;

}

// 获取锁失败,等待20毫秒继续请求

try {

log.info("等待20 nanoSeconds key:{},value:{}", key, value);

TimeUnit.NANOSECONDS.sleep(20);

} catch (InterruptedException e) {

log.info("等待20 nanoSeconds 异常 key:{},value:{}", key, value);

e.printStackTrace();

}

}

}

/**

* 解锁

*

* @param key

* @param value

*/

public void unlock(String key, String value) {

try {

redisTemplate.opsForValue().getOperations().delete(key);

} catch (Exception e) {

e.printStackTrace();

}

}

}

2.应用举例

  我们以得到锁之后的第一个线程才处理业务为例,给出一个例子:

String redisKey = RedisPrefix.MY_BIZ + name;

try {

boolean lockResult = redisLock.lock(redisKey, name);

if (lockResult) {

userInfo = userService.findUser(name);

if (userInfo == null) {

// 抢到锁,且为第一个到来的线程,开始处理业务。

userService.createUserInfo(name);

}

}

} catch (Exception e) {

e.printStackTrace();

log.error("redis lock error:", e);

} finally {

redisLock.unlock(redisKey, name);

}

以上是 简易的Redis分布式事务锁 的全部内容, 来源链接: utcz.com/z/519122.html

回到顶部