当前位置: 首页 > 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.rkmt.cn/news/11816.html

相关文章:

  • 深入解析:SQL 字符串函数高频考点:LIKE 和 SUBSTRING 的区别
  • Etcd详解:Kubernetes的大脑与记忆库 - 实践
  • go 语法里变量前面增加、*区别
  • 20250922_QQ_backdoor
  • 卓伊凡的第一款独立游戏-unity安装运行设置以及熟悉整体unity游戏开发和unity editor【02】-优雅草卓伊凡
  • 9.24(补)
  • 亚马逊与AWS如何通过漏洞赏金计划构建深度安全防御
  • 详细介绍:锚定效应(解释+类型区分+商业及生活应用+如何避免)
  • 【JavaEE】SpringIoC与SpringDI - 详解
  • 24.Linux硬盘分区管理 - 详解
  • CCF CSP-J 2025_from_黄老师_km
  • AI一周资讯 250918-250925
  • SQL注入-联合注入
  • 详细介绍:Windows安装PostgreSQL入门操作手册
  • 一种CDN动态加速首次访问加速方法
  • 使用vosk模型进行语音识别
  • 【LeetCode】122. 买卖股票的最佳时机 II
  • Ansible + Docker 部署 Apache Kafka 3.9 集群
  • 完整教程:K230基础-PWM控制介绍及应用
  • 什么是UDFScript用户自定义脚本
  • 高端网站设计中的微交互:细节如何决定用户体验
  • Openwrt-DDNS 配置详解
  • 【2025.9.16】关于举办PostgreSQL数据库管理人才研修与评测班的通知
  • 隐藏在众目睽睽之下:从PEB中解除恶意DLL的链接
  • 详细介绍:Java 领域中 Java-EE 的异步编程实现
  • 深入解析:豆包Seedream 4.0:全面测评、玩法探索与Prompt解读
  • 破局与进化:火山引擎Data Agent从落地实践到架构未来
  • 五项能力斩获满分!天翼云云WAF获IDC权威认可!
  • lvgl 9.3 style使用导致内存泄漏问题
  • king3399 编译报错