
戴嘎猴啊,我是程序员卡卡罗特~

在分布式系统架构中,随着业务规模的扩大,我们不可避免地会遇到多节点并发操作共享资源的问题。
在企业真实项目中,Redis分布式锁一般是怎么用的呢?
在单体应用中,我们可以用synchronized或ReentrantLock等本地锁解决并发问题。
但当系统拆分为微服务,部署在多台服务器后,本地锁就失去了作用——因为不同服务器上的进程无法感知彼此的锁状态。
Redis分布式锁正是为解决这类跨服务器节点并发问题而生:
•
保证同一时间,只有一个服务器节点的一个进程能执行一段代码
•
防止因并发操作导致的数据不一致(如重复数据、数据错乱)
用Redis分布式锁解决用户重复注册问题
用户注册场景中,如果同一用户(比如同一手机号)在极短时间内提交多次注册请求,可能导致重复创建用户记录。
实际上,前端会做防抖校验,也是防止用户重复点击的,但是后端是必须要做的!因为万一前端没做呢?或者有人在你的网站通过代码调用注册接口呢🤔,emmm...

我们可以用Redis分布式锁来避免这种情况。
这个类可以作为公共类使用
@Component
public class RedisDistributedLock {
@Autowired
private StringRedisTemplate redisTemplate;
// 锁的过期时间(30秒),防止死锁
private static final long LOCK_EXPIRE_MILLIS = 30000;
// 尝试获取锁的超时时间(5秒)
private static final long ACQUIRE_TIMEOUT_MILLIS = 5000;
/**
* 尝试获取分布式锁
* @param lockKey 业务唯一标识(如手机号)
* @return 锁的value(用于释放锁时的身份验证)
*/
public boolean lock(String lockKey) {
// SET NX PX:不存在则设置,同时设置过期时间
return redisTemplate.opsForValue().setIfAbsent(lockKey, "1", Duration.ofMillis(LOCK_EXPIRE_MILLIS));
}
/**
* 释放分布式锁
* @param lockKey 业务唯一标识
*/
public void unlock(String lockKey) {
if (lockValue == null) {
return;
}
redisTemplate.delete(lockKey);
}
}
@Service
public class UserRegistrationService {
@Autowired
private RedisDistributedLock distributedLock;
@Autowired
private UserRepository userRepository;
/**
* 用户注册方法
* @param phone 手机号(作为唯一标识)
* @param userInfo 用户信息
* @return 注册结果
*/
public Result registerUser(String phone, UserInfo userInfo) {
boolean locked = false;
String lockKey = "USER_REGISTER_LOCK_" + phone;
try {
// 1、加锁失败,提前退出
if (!distributedLock.lock(lockKey)) {
return Result.fail("操作过于频繁,请稍后再试");
}
// 2. 检查用户是否已注册(临界区操作)
User existingUser = userRepository.findByPhone(phone);
if (existingUser != null) {
return Result.fail("该手机号已注册");
}
// 3. 执行注册逻辑
User newUser = new User();
newUser.setPhone(phone);
newUser.setUsername(userInfo.getUsername());
// ... 设置其他用户信息
userRepository.save(newUser);
return Result.success("注册成功", newUser.getId());
} finally {
if (locked) {
distributedLock.unlock(lockKey);
}
}
}
}
return redisTemplate.opsForValue().setIfAbsent(lockKey, "1", Duration.ofMillis(LOCK_EXPIRE_MILLIS));
核心是这段代码:当redis存在lockKey的时候,返回的是false。不存在的时候,返回的是true。
底层是依赖redis的set nx明了,来保证加锁的原子性。
Redis分布式锁是解决分布式系统并发问题的重要工具,它通过Redis的单线程特性和原子命令,为跨节点的临界区操作提供了可靠的互斥保障。
在用户注册、商品秒杀、订单创建等核心场景中,合理使用分布式锁能有效避免数据不一致问题,保障系统的稳定性和数据准确性。
需要注意的是,Redis分布式锁在某些情况存在坑🤔,在实际使用中还需考虑Redis集群环境下的锁可靠性、锁过期时间设置等细节,这些我们会在后续文章中深入探讨。
