主页 > 游戏开发  > 

基于Redisson分布式锁实现报名人数限制功能

基于Redisson分布式锁实现报名人数限制功能
1:pom依赖 <!-- redisson --> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.6.5</version> </dependency> 2:相关配置 2.1 RedissonConfig package com.ly.cloud.config; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; @Configuration public class RedissonConfig { @Value("${spring.redis.host}") private String address; @Value("${spring.redis.port}") private String port; @Value("${spring.redis.password}") private String password; @Bean public RedissonClient redissonClient() { Config config = new Config(); config.useSingleServer() .setAddress("redis://" + address + ":"+port) .setPassword(password) .setTimeout(10000) .setRetryAttempts(5) .setRetryInterval(2000) .setConnectionPoolSize(64) .setConnectionMinimumIdleSize(24) // 保持连接活动 .setKeepAlive(true) // 发送PING命令的间隔时间; .setPingConnectionInterval(30000); return Redisson.create(config); } } 2.2 RedissonDistributedLock package com.ly.cloud ponents; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.concurrent.TimeUnit; @Component public class RedissonDistributedLock { @Resource private RedissonClient redissonClient; public boolean tryLock(String lockKey, long expireTime, long waitTime) throws InterruptedException { RLock lock = redissonClient.getLock(lockKey); return lock.tryLock(waitTime, expireTime, TimeUnit.MILLISECONDS); } public void releaseLock(String lockKey) { RLock lock = redissonClient.getLock(lockKey); if (lock.isHeldByCurrentThread()) { lock.unlock(); } } } 3:业务代码 @Override public Boolean insertLectureRegistration(String lectureId) throws InterruptedException { String loginUserId = LoginUserUtil.getLoginUserId(); // 判断当前 用户是否已经报名该讲座 // if (lectureMessageMapper.getIsRegistrationLectrure(lectureId,loginUserId) > 0) { // throw new BusinessException("用户:" + loginUserId + "已报名成功,无需第二次报名!"); // } LectureRegistration registration = new LectureRegistration(); registration.setId(IdUtil.simpleUUID()); registration.setUserId(loginUserId); registration.setUserName(userMapper.getUserName(loginUserId)); registration.setRegistrationTime(DateTimeUtils.getTimeStamp()); String departmentId = departmentMapper.getDepartmentById(loginUserId); registration.setRegistrationDepartmentNumber(departmentId); registration.setRegistrationDepartmentName(departmentMapper.getDepartmentName(departmentId)); registration.setLectureNumber(lectureId); registration.setDeleted("1"); int total = lectureMessageMapper.getRegistrationPeopleTotal(lectureId); if (total == 0) { return lectureMessageMapper.insertLectureRegistration(registration) > 0; } String lockKey = lectureId + "stock"; // 只在 Redis 不存在时初始化库存 Boolean stockExists = stringRedisTemplate.hasKey(lockKey); if (Boolean.FALSE.equals(stockExists)) { stringRedisTemplate.opsForValue().setIfAbsent(lockKey, String.valueOf(total)); } boolean locked = redissonDistributedLock.tryLock(lectureId, 1000, 5000); try { if (locked) { stringRedisTemplate.watch(lockKey); String stockStr = stringRedisTemplate.opsForValue().get(lockKey); if (stockStr == null) { throw new BusinessException("讲座报名名额数据异常"); } int stock = Integer.parseInt(stockStr); if (stock > 0) { stringRedisTemplate.setEnableTransactionSupport(true); stringRedisTemplate.multi(); Long realStock = stringRedisTemplate.opsForValue().increment(lockKey, -1); List<Object> results = stringRedisTemplate.exec(); if (!CollectionUtils.isEmpty(results)) { logger.info("讲座报名名额剩余:{}", realStock); return lectureMessageMapper.insertLectureRegistration(registration) > 0; } else { throw new BusinessException("讲座报名名额已用完,无法报名!"); } } else { throw new BusinessException("讲座报名名额已用完,无法报名!"); } } } catch (Exception e) { throw new BusinessException("报名失败:", e); } finally { if (locked) { redissonDistributedLock.releaseLock(lectureId); } } return true; } 4:并发测试

标签:

基于Redisson分布式锁实现报名人数限制功能由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“基于Redisson分布式锁实现报名人数限制功能