Commit 88f90166 authored by 杨锐's avatar 杨锐

redis分布式锁,处理/user/center/save/userExtInfo并发问题,导致MySQLIntegrityConstraintViolationException

parent e4e73cce
package cn.quantgroup.xyqb.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.RandomStringGenerator;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.data.redis.core.RedisCallback;
......@@ -17,14 +18,14 @@ import java.util.Random;
* // CODE
* }
* } catch (InterruptedException e) {
* LOGGER.warn("获取锁失败:lockKey:{},exception:{}",redisLock.getLockKey(),e.getMessage());
* log.warn("获取锁失败:lockKey:{},exception:{}",redisLock.getLockKey(),e.getMessage());
* }finally {
* redisLock.unlock();
* }
* </pre>
*/
@Slf4j
public class RedisLock {
private final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(RedisLock.class);
private RedisTemplate redisTemplate;
/**
* Lock key path.
......@@ -56,7 +57,7 @@ public class RedisLock {
public RedisLock(RedisTemplate redisTemplate, String lockKey) {
this.redisTemplate = redisTemplate;
this.lockKey = "lock:".concat(lockKey).concat("_lock");
logger.info("准备锁 lock:{},{}", getLockKey());
log.info("准备锁 lock:{},{}", getLockKey());
}
/**
......@@ -107,7 +108,7 @@ public class RedisLock {
return serializer.deserialize(data);
});
} catch (Exception e) {
logger.error("get redis error, key " + key + ": {}", e);
log.error("get redis error, key " + key + ": {}", e);
throw new InvalidDataAccessResourceUsageException(e.getMessage());
}
return obj != null ? obj.toString() : null;
......@@ -134,7 +135,7 @@ public class RedisLock {
return success;
});
} catch (Exception e) {
logger.error("setNX redis error, key “" + key + "”: {}", e);
log.error("setNX redis error, key “" + key + "”: {}", e);
}
return obj != null ? (Boolean) obj : false;
}
......@@ -156,7 +157,7 @@ public class RedisLock {
return serializer.deserialize(ret);
});
} catch (Exception e) {
logger.error("getSet redis error, key : {}", key);
log.error("getSet redis error, key : {}", key);
}
return obj != null ? (String) obj : null;
}
......@@ -179,7 +180,7 @@ public class RedisLock {
if (this.setNX(lockKey, expiresStr)) {
// lock acquired
this.expiresStr = expiresStr;
logger.info("获取锁成功 lock:{}", getLockKey());
log.info("获取锁成功 lock:{}", getLockKey());
return true;
}
......@@ -199,7 +200,7 @@ public class RedisLock {
//[分布式的情况下]:如过这个时候,多个线程恰好都到了这里,但是只有一个线程的设置值和当前值相同,他才有权利获取锁
// lock acquired
this.expiresStr = expiresStr;
logger.info("获取锁成功(前一个锁超时) lock:{}", getLockKey());
log.info("获取锁成功(前一个锁超时) lock:{}", getLockKey());
return true;
}
}
......@@ -213,8 +214,8 @@ public class RedisLock {
Thread.sleep(sleepTime);
} catch (InvalidDataAccessResourceUsageException e) {
if (retryCount > 3) {
logger.error("redis有可能出现问题不能获取lockKey:{}", lockKey);
logger.warn("redis lock 3次重试仍异常,lockKey: {} 进行降级服务....", lockKey);
log.error("redis有可能出现问题不能获取lockKey:{}", lockKey);
log.warn("redis lock 3次重试仍异常,lockKey: {} 进行降级服务....", lockKey);
return true;
}
retryCount++;
......@@ -225,7 +226,7 @@ public class RedisLock {
Thread.sleep(100); }
}
}
logger.info("锁失败 lock:{}", getLockKey());
log.info("锁失败 lock:{}", getLockKey());
return false;
}
......@@ -240,18 +241,18 @@ public class RedisLock {
try {
expStr = this.get(lockKey);
} catch (InvalidDataAccessResourceUsageException e) {
logger.warn("redis unlock 异常, lockKey:{} 进行降级服务....", lockKey);
log.warn("redis unlock 异常, lockKey:{} 进行降级服务....", lockKey);
}
if (expStr == null || this.expiresStr.equals(expStr)) {
redisTemplate.delete(lockKey);
logger.info("解锁成功 lock:{}", getLockKey());
log.info("解锁成功 lock:{}", getLockKey());
return;
}
} catch (Exception e) {
logger.error("redis unlock 异常 lockKey "+lockKey+":{} ", e);
log.error("redis unlock 异常 lockKey "+lockKey+":{} ", e);
}
}
logger.warn("没有锁或者因非本对象产生的锁,不能进行解锁,因为是不安全的");
log.warn("没有锁或者因非本对象产生的锁,不能进行解锁,因为是不安全的");
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment