SETNX命令简介
SETNX key value
将key的值设为value,并且仅当key不存在。
若给定的key已经存在,则SETNX不做任何操作。
SETNX 是SET if Not eXists的简写。
返回整数,具体为
1,当 key 的值被设置
0,当 key 的值没被设置
实现分布式事务的java代码通用方法
public Boolean getHadoopLock(String lock) {
// 利用lambda表达式
return (Boolean) redisTemplate.execute( (RedisCallback) connection -> {
long expireAt = System.currentTimeMillis() + RedisPrefixKeyConst.LOCK_EXPIRE + 1;
Boolean acquire = connection.setNX( lock.getBytes(), String.valueOf( expireAt ).getBytes() );
if (acquire) {
return true;
} else {
byte[] value = connection.get( lock.getBytes() );
if (Objects.nonNull( value ) && value.length > 0) {
long expireTime = Long.parseLong( new String( value ) );
if (expireTime < System.currentTimeMillis()) {
// 如果锁已经过期
byte[] oldValue = connection.getSet( lock.getBytes(),
String.valueOf( System.currentTimeMillis() + RedisPrefixKeyConst.LOCK_EXPIRE + 1 ).getBytes() );
// 防止死锁
return Long.parseLong( new String( oldValue ) ) < System.currentTimeMillis();
}
}
}
return false;
} );
}
如何正确使用分布式锁?
String lockKey = RedisConstant.CSDN_APPLY_LOCK_REPT;
Boolean flag = getHadoopLock( lockKey );
if (!flag) {
// 设置失败次数计数器, 当到达5次时, 返回失败
int failCount = 1;
while (failCount <= 5) {
// 等待100ms重试
try {
Thread.sleep( 100l );
} catch (InterruptedException e) {
e.printStackTrace();
}
if (getHadoopLock( lockKey )) {
// 执行逻辑操作
flag = true;
} else {
failCount++;
}
}
return ;
}
//如果获取到锁的话,就执行相应的的代码
if(flag){
/**
此处放置需要要高并发的代码
*/
//代码执行成功则释放锁
redisTemplate.delete( lockKey );
}