因为自己做的项目是支付系统,调用第三方支付的,公司用的是redis分布式锁,从开始知道项目中用的是redis锁到现在想写这篇关于redis锁的文章,差不多半年了,这个过程也是有时间才看看,断断续续的,现在写下来,也没有完全的理解项目中的锁是怎么实现的,但是这个过程中对redis锁有个大概的了解了,这边文章没有太多的参考价值,只是自己在项目中遇到的问题,我的boss也没有给我答复,我间接的想知道为什么,boss只是跟我说要是真的有问题,生成环境早都出问题,没有问题你不要怀疑,再去看看吧,就这样被打发回来了
问题:
在代码中执行testNg跑的时候根据key在redis上给key赋值为long类型的时间戳,支付的时候加上锁,最后执行finally 时,释放锁,执行的是del命令,但是执行完再看对应的key没有被删除,看代码是当前的时间戳要小于等于设置的时间戳的判断不满足(为什么是当前时间戳+5000*2+1标红部分)代码如下:
private boolean acquireLock(long lockTime) {
long lockTimeOut = lockTime * 2L;
long expiretime = System.currentTimeMillis() + lockTimeOut + 1L;
Long value = this.redisCacheUtils.setnx(this.key, String.valueOf(expiretime));
if(value != null && value.longValue() == 1L) {
this.locked = true;
return this.locked;
} else {
String curLockTimeStr = this.redisCacheUtils.get(this.key);
if(StringUtils.isEmpty(curLockTimeStr) || System.currentTimeMillis() > Long.valueOf(curLockTimeStr).longValue()) {
expiretime = System.currentTimeMillis() + lockTimeOut + 1L;
curLockTimeStr = this.redisCacheUtils.getSet(this.key, String.valueOf(expiretime));
if(StringUtils.isBlank(curLockTimeStr) || System.currentTimeMillis() > Long.valueOf(curLockTimeStr).longValue()) {
this.locked = true;
return this.locked;
}
}
return false;
}
}
顺便把解锁的代码也show下:
public void unlock() { try { if(this.locked) { String curLockTimeStr = this.redisCacheUtils.get(this.key); if(StringUtils.isNotEmpty(curLockTimeStr) && System.currentTimeMillis() <= Long.valueOf(curLockTimeStr).longValue()) { this.redisCacheUtils.del(this.key); } } } catch (Exception var2) { this.logger.logException(var2); } }
这个文章接着写:之前一直不理解的场景,测试的时候 发现一个场景,支付结束后返回个上游系统,有明确微信支付失败,但是客户端返回报错(提示redis锁的问题),问题出现的场景 被我猜到是什么场景,支付时上游系统没有接受到返回结果超时,然后上游系统继续调轮询,这个时候轮询返回redis锁没有释放,我一直怀疑有问题(我本地跑的时候锁没有删掉,理论上市应该删除的,不知道什么问题?)测试复现这个问题后,第一时间通过客户RedisDesktopManager查看锁有没有被删除,这个时候看是被删掉的,然后去问boss,boss的意思是上游系统这个时候是超时的,紧接着调我轮询(支付和轮询用的是同一把锁),这个时候支付还没有处理完,所有返回给客户端redis锁的问题,这个可以解释我之前的疑惑.
度娘了关于redis锁的实现,有很多方法,因为最近把redis的pdf过一篇,想研究一遍,度娘看到使用脚本的方式实现redis分布式锁,只是扫了一遍,想表达的是实现redis分布式锁有很多实现方式,不一定要用这种方式
标红的部分 有人理解的烦请留言告知,谢谢!