当前位置: 首页 > news >正文

redis实现分布式锁1

在集群下的并发问题:

image

业务流程:

image

具体实现:

ILock

点击查看代码

package com.hmdp.utils;public interface ILock {// 获取锁boolean tryLock(long timeoutSec);// 释放锁void unlock();
}

SimpleRedisLock

点击查看代码

package com.hmdp.utils;import org.springframework.data.redis.core.StringRedisTemplate;import java.util.concurrent.TimeUnit;public class SimpleRedisLock implements ILock {private String name;private StringRedisTemplate stringRedisTemplate;private static final String KEY_PREFIX = "lock:";public SimpleRedisLock(String name, StringRedisTemplate stringRedisTemplate) {this.name = name;this.stringRedisTemplate = stringRedisTemplate;}@Overridepublic boolean tryLock(long timeoutSec) {// 获取线程的标识long threadId = Thread.currentThread().getId();// 获取锁Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(KEY_PREFIX + name, threadId + "", timeoutSec, TimeUnit.SECONDS);return Boolean.TRUE.equals(success);}@Overridepublic void unlock() {// 释放锁stringRedisTemplate.delete(KEY_PREFIX + name);}
}

VoucherOrderServiceImpl

点击查看代码

package com.hmdp.service.impl;import com.hmdp.dto.Result;
import com.hmdp.entity.SeckillVoucher;
import com.hmdp.entity.VoucherOrder;
import com.hmdp.mapper.VoucherOrderMapper;
import com.hmdp.service.ISeckillVoucherService;
import com.hmdp.service.IVoucherOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.utils.RedisIdWorker;
import com.hmdp.utils.SimpleRedisLock;
import com.hmdp.utils.UserHolder;
import org.springframework.aop.framework.AopContext;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;
import java.time.LocalDateTime;/*** <p>*  服务实现类* </p>** @author ztn* @since 2025-09-23*/
@Service
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {@Resourceprivate ISeckillVoucherService seckillVoucherService;@Resourceprivate RedisIdWorker redisIdWorker;@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result seckillVocher(Long voucherId) {// 1.查询优惠券SeckillVoucher voucher = seckillVoucherService.getById(voucherId);// 2.判断秒杀是否开始if(voucher.getBeginTime().isAfter(LocalDateTime.now())){return Result.fail("秒杀尚未开始");}// 3.判断秒杀是否结束if(voucher.getEndTime().isBefore(LocalDateTime.now())){return Result.fail("秒杀已经结束");}// 4.判断库是否充足if(voucher.getStock() < 1){return Result.fail("库存不足");}Long userId = UserHolder.getUser().getId();// 创建锁对象SimpleRedisLock lock = new SimpleRedisLock("order:" + userId, stringRedisTemplate);// 获取锁boolean isLock = lock.tryLock(1200);// 判断是否获取锁成功if(!isLock){// 获取锁失败,返回错误或重试return Result.fail("不允许重复下单");}try {// 获取代理对象(事务)IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();return proxy.createVoucherOrder(voucherId);}finally {// 释放锁lock.unlock();}}@Transactionalpublic  Result createVoucherOrder(Long voucherId) {// 5.一人一单Long userId = UserHolder.getUser().getId();// 5.1 查询订单int count = query().eq("user_id", userId).eq("voucher_id", voucherId).count();// 5.2 判断是否存在if(count > 0){// 用户已经购买过了return Result.fail("用户已经购买过一次了");}// 6.扣减库存boolean success = seckillVoucherService.update().setSql("stock = stock - 1") // set stock =stock -1.eq("voucher_id", voucherId)
//                .eq("stock",voucher.getStock()) // where id = ? and stock = ?.gt("stock",0) // where id = ? and stock > 0.update();if(!success){return Result.fail("库存不足");}// 7.创建订单VoucherOrder voucherOrder = new VoucherOrder();// 7.1订单idlong orderId = redisIdWorker.nextId("order");voucherOrder.setId(orderId);// 7.2用户idvoucherOrder.setUserId(userId);// 7.3代金券idvoucherOrder.setVoucherId(voucherId);save(voucherOrder);// 8.返回订单idreturn Result.ok(orderId);}
}
http://www.hskmm.com/?act=detail&tid=17302

相关文章:

  • 完整教程:(13)GPS/无GPS转换
  • Transformer自回归关键技术:掩码注意力原理与PyTorch完整实现
  • 第四篇
  • PyTorch图神经网络(六)
  • Qwen多模态系列模型笔记—Qwen-VL
  • go 语法里变量前面增加、*区别
  • 历程回顾-(2024-2025)
  • CF Round 1053(2150 2151) 总结
  • 20250922_QQ_backdoor
  • 实用指南:【Java八股文】13-中间件面试篇
  • AT_agc012_d [AGC012D] Colorful Balls
  • 02、Python从入门到癫狂:函数与资料容器
  • 第二周第四天2.4
  • 9/25
  • 关闭Edge浏览器页面的圆角效果
  • 搜索二维矩阵II-leetcode
  • Rust/C/C++ 混合构建 - Cmake集成Cargo编译动态库
  • 第12章 day13 关于json请求体
  • CF1349
  • 学习敏捷课程PSM,自考证书分享
  • Rust/C/C++ 混合构建 - 用Bazel构建Rust与C
  • 9.24(补)
  • 9月25号
  • CCF CSP-J 2025_from_黄老师_d
  • 亚马逊与AWS如何通过漏洞赏金计划构建深度安全防御
  • sync.pool 面试题
  • 【JavaEE】SpringIoC与SpringDI - 详解
  • 24.Linux硬盘分区管理 - 详解
  • CCF CSP-J 2025_from_黄老师_km
  • AI一周资讯 250918-250925