redis乐观锁、事务、分布式锁的实现
配置,需要设置setEnableTransactionSupport,开启事务
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setEnableTransactionSupport(true);//开启支持事务 multi exec
return template;
}
实现理念
/**
* redis 乐观锁 + 事务 的实现
*/
@Test
public void lockDemo1() {
try {
redisTemplate.watch("name");
redisTemplate.multi();
//进行事务代码
// .....
// .....
// .....
//最后提交事务
List<Object> exec = redisTemplate.exec();
if (exec.isEmpty()) {
System.out.println("操作失败");
}
} catch (RuntimeException e) {
//出现异常撤销
redisTemplate.discard();
} finally {
redisTemplate.unwatch();
}
}
使用 setnx(set if not exist)实现分布式锁
setnx性质:如果不存在那么返回 0 ,不存在返回 1 。
/**
* redis 使用setnx命令实现分布式锁
*/
@Test
public void lockDemo() {
Supplier<Boolean> getLock = () -> {
Boolean b = redisTemplate.opsForValue().setIfAbsent("lock-name", "lock-val");
return b != null && b;
};
try {
//循环获取分布式锁
while (!getLock.get()) ;
//进行的业务代码
synchronized (RedisTest.class) {
//.....
}
} finally {
//防止异常,释放锁
redisTemplate.delete("lock-name");
}
}