基于Redis实现分布式锁

问题描述
服务A和服务B都需要访问共享资源C。这时就会发生共服务A和服务B都去抢占享资源C,为了避免这种抢占,就需要引入分布式锁。

分布式锁介绍
分布式锁:控制分布式系统有序的去对共享资源进行操作,通过互斥来保证数据的一致性。

解决方案

基于redis实现分布式锁
可以使用reids中的setnx(SET if NOT exixts)命令实现。命令会在指定key不存在时去给key设置指定的值,将该值保存在redis中,当有其他服务来访问时由于没有该值就会导致访问失败。

这种加锁的思路是,如果 key 不存在则为 key 设置 value,如果 key 已存在则 SETNX 命令不做任何操作

  • 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功
  • 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败
  • 客户端A执行代码完成,删除锁
  • 客户端B在等待一段时间后再去请求设置key的值,设置成功
  • 客户端B执行代码完成,删除锁

代码演示

点击查看代码
/**
 * 加锁
 *
 * @param name,锁名
 * @param expire,过期时间的值
 * @return
 */
public String tryLock(String name, long expire) {
    name = name + "_lock";
    String token = UUID.randomUUID().toString();
    RedisConnectionFactory factory = stringRedisTemplate.getConnectionFactory();
    RedisConnection conn = factory.getConnection();
    try {

        //参考redis命令:
        //set key value [EX seconds] [PX milliseconds] [NX|XX]
        Boolean result = conn.set(
                name.getBytes(),
                token.getBytes(),
                Expiration.from(expire, TimeUnit.MILLISECONDS),
                RedisStringCommands.SetOption.SET_IF_ABSENT //NX
        );
        if (result != null && result)
            return token;
    } finally {
        RedisConnectionUtils.releaseConnection(conn, factory,false);
    }
    return null;
}
posted @ 2023-06-19 12:10  wzh_Official  阅读(25)  评论(0编辑  收藏  举报