业务场景分析
多个并发请求同时修改同一份数据, 比如多个营业员并发对同一个客户的资料进行修改。 同时修改同一份数据会并发冲突,导致数据不正确的可能,对业务产生不可预估的影响。目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题。
解决方案
对于分布式锁可以基于数据库实现分布式锁 ,但带来的问题是性能不足,无法满足大型应用的高并发使用场景。这时基于缓存(Redis等)去实现分布式锁,带来了显著性能优势。
Redis实现分布式锁的原理是基于: 存在判断KEY是否存在的命令,以及KEY设置TTL,防止死锁的机制。
下面是一个简单的实现思路:
(1)获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。
(2)获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
(3)释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。
由于开源已经有非常多成熟的方案, 下面是基于redisson(一个开源的JAVA redis库)实现分布式锁,可参考如下示例:
maven
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.25.0</version>
</dependency>
示例代码
RLock lock = redisson.getLock("myLock");
// traditional lock method
lock.lock();
// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);
// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {
...
} finally {
lock.unlock();
}
}