更新 2020-12-20
请直接使用 redisTemplate.opsForValue().increment(KEY) 生成不重复的主键解决重复问题,不需要编写 Lua 脚本。
前言
由于项目需要在用户注册的时候随机给用户生成一个用户名,一开始的想法是使用RandomStringUtils随机生成一个字符串,然而这样直接使用还是感觉有一天会生成重复的用户名,因此想到了通过Redis自增id来防止用户名冲突。
实现方案
具体的用户名实现格式为{自定义前缀}_{随机字符串}_{自增id},这样因为自增id的存在,就不会出现重复的用户名。
Redis自增id实现
编写lua自增编号脚本
local id = redis.call('GET', KEYS[1])
if not id then
redis.call('SET', KEYS[1], ARGV[1])
end
return redis.call('INCR', KEYS[1])
定义RedisScript
/**
* 描述:Redis相关配置
*
* @author: xhsf
* @create: 2020/11/23 13:45
*/
@Configuration
public class RedisConfig {
/**
* 自增id Redis脚本
* @return 自增id值
*/
@Bean("incrementIdRedisScript")
public RedisScript<Long> incrementIdRedisScript() {
DefaultRedisScript<Long> incrementIdRedisScript = new DefaultRedisScript<>();
incrementIdRedisScript.setResultType(Long.class);
incrementIdRedisScript.setScriptSource(new ResourceScriptSource(
new ClassPathResource("/redis/lua/IncrementId.lua")));
return incrementIdRedisScript;
}
}
使用
这里incrementIdRedisScript是上面定义的Bean,SIGN_UP_USERNAME_INCREMENT_ID_REDIS_KEY是Redis里面自增id的key,SIGN_UP_USERNAME_INCREMENT_ID_REDIS_START_VALUE是自增id起始值。
Long incrementId = redisTemplate.execute(incrementIdRedisScript,
Collections.singletonList(SIGN_UP_USERNAME_INCREMENT_ID_REDIS_KEY),
SIGN_UP_USERNAME_INCREMENT_ID_REDIS_START_VALUE);