分布式锁

什么是分布式

分布式结构就是将一个完整的系统,按业务功能,拆分成一个个独立的子系统,在分布式结构中,每个子系统就被称为”服务”。

在java中,synchronized关键词在我们的代码中是常见的,这些都是本地锁,只能解决一台服务器并发问题。

但随着业务增大,我们无法保证某个数据的改变是同一台服务器操作的。因此,我们需要一个能锁住所有服务器的锁—分布式锁。

使用Redis分布式锁,就需要用到Reddission客户端,它提供的功能远远超出了一个Redis客户端的范畴。在支持基本Redis功能的同时,提供了一些高级服务:

  1. 远程调用
  2. 分布式锁
  3. 分布式对象、容器

使用依赖:

<dependencies>
    <dependency>
        <groupId>org.redisson</groupId>
        <artifactId>redisson-spring-boot-starter</artifactId>
        <version>3.13.0</version>
    </dependency>
</dependencies>

装载一下对象

@Autowired
private RedissonClient redissonClient;

实现Redis分布式锁大致需要三步:

1.取得锁

RLock rLock = redissonClient.getLock("CUSTOM_NAME");

redissonClient.getLock() 得到一个 Redis 锁对象,方法参数是 字符串 类型的自定义锁名称,不一定要用数据 Key ,一般推荐用容易理解的、业务相关的名称。

CUSTOM_NAME 只是代码举例哦

为了减少冲突、明确含义、易于理解和维护,不要以简单的数字 id 值作为 Redis 中的数据 Key,推荐的格式是:

productId-1-stock

2.上锁

使用:

rLock.lock();
  1. 并发情况下,每个线程都会竞争锁:
  2. 竞争成功(获取锁)的线程会继续允许
  3. 竞争失败的线程会被禁用,并且重新获取锁之前,该线程将一直处于休眠状态。

简单说,抢不到锁的线程会持续等待,所有使用锁要特别小心

3.解锁

rLock.unlock();

有上锁就必然要解锁,否则会导致线程持续等等而产生死锁,系统也就卡死了。

所以,推荐把业务操作放在try–catch–finally中:

try {
  rLock.lock();
  // 抢购业务逻辑
} catch (Exception e) {
    LOG.error("some error. ", e);
} finally {
    rLock.unlock();
}