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

南宁网站平台wordpress文章页的宽度

南宁网站平台,wordpress文章页的宽度,网站建设与网页制作招聘,网站备案 假通信地址超卖与一人一单问题是并发场景下常见的挑战,尤其是在库存管理、限时抢购等业务中。乐观锁和悲观锁是解决这类问题的两种主要方案,它们的核心思想和适用场景有所不同。在解决上述业务问题之前先来了解一下什么是乐观锁和悲观锁?一、乐观锁乐观…

        超卖与一人一单问题是并发场景下常见的挑战,尤其是在库存管理、限时抢购等业务中。乐观锁和悲观锁是解决这类问题的两种主要方案,它们的核心思想和适用场景有所不同。

        在解决上述业务问题之前先来了解一下什么是乐观锁和悲观锁?

一、乐观锁

        乐观锁认为并发冲突概率较低,因此不主动锁定资源,而是在更新数据时检查资源是否被其他线程修改过。如果未被修改,则正常更新;如果已被修改,则放弃操作或重试。它是一种 "先做后验" 的策略。

        实现方式通常通过版本号机制实现:在表中增加version字段,每次更新时对比版本号,一致则更新并递增版本号,不一致则更新失败。

二、悲观锁

        悲观锁认为并发操作会频繁冲突,因此在操作数据时会直接锁定资源,阻止其他线程访问,直到当前操作完成并释放锁。它是一种 "先防后做" 的策略。例如Synchronized、Lock都属于
悲观锁。

        实现方式在数据库层面,通常使用for update语句实现行级锁;在 Java 代码中可配合事务(@Transactional)确保锁的有效性。

三、乐观锁与悲观锁的适用场景以及优缺点

        针对于不同的场景应该采用不同的策略来实现性能的最大化开发。

1.乐观锁适用场景以及优缺点

适用场景

  • 读多写少,并发冲突概率较低的场景。

  • 系统追求高吞吐量,能够容忍偶尔的更新失败。

  • 业务逻辑复杂,需要较长时间,不适合长时间持有锁。

优点

  • 性能好:没有锁的开销,大大提高了高并发下的吞吐量。

  • 无死锁风险。

缺点

  • 实现稍复杂。

  • 如果冲突频繁,重试次数会很多,可能降低体验。

  • 是一种“乐观”策略,无法保证每次请求都成功。

2.悲观锁适用场景以及优缺点

适用场景

  • 写操作非常频繁,冲突概率很高的场景。

  • 对数据一致性要求极高,不允许出现任何并发问题的场景。

  • 业务逻辑执行时间较长,需要在整个过程中保持锁定。

优点

  • 保证强一致性,实现起来简单直接。

  • 避免了任何并发冲突。

缺点

  • 性能开销大:加锁是数据库层面的操作,会阻塞其他等待锁的事务,导致系统吞吐量下降。

  • 死锁风险:如果多个事务相互等待对方持有的锁,容易引发死锁。

  • 不适用于高并发读的场景,会严重影响读性能。

四、超卖业务问题解决示例

业务说明:对于活动报名业务,在高并发场景下可能会出现报名人数超出活动的人数限制,因此采用乐观锁来解决该业务问题。

        没必要在数据库中添加version字段,我们可以使用已有字段来代替,如下采用 ParticipantCount < ParticipantLimit 即可。

/*** 活动报名*/@Transactional(rollbackFor = Exception.class)@Overridepublic void registerActivity(Long activityId, Long userId) {// 1. 查询活动信息Activity activity = baseMapper.selectById(activityId);// 2. 查询用户是否报名LambdaQueryWrapper<ActivityUser> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(ActivityUser::getActivityId, activityId).eq(ActivityUser::getUserId, userId);Long count = activityUserMapper.selectCount(queryWrapper);if (count > 0) {throw new ActivityException("用户已报名");}// 3. 检查人数限制if (activity.getParticipantCount() >= activity.getParticipantLimit()) {throw new ActivityException("活动已报满");}// 4. 更新活动报名人数(乐观锁解决并发超卖问题)LambdaUpdateWrapper<Activity> updateWrapper = new LambdaUpdateWrapper<>();updateWrapper.eq(Activity::getActivityId, activityId).lt(Activity::getParticipantCount, activity.getParticipantLimit()).setSql("participant_count = participant_count + 1");int update = baseMapper.update(updateWrapper);if (update == 0) {throw new ActivityException("活动已报满");}// 5. 记录报名信息ActivityUser activityUser = ActivityUser.builder().activityId(activityId).userId(userId).build();activityUserMapper.insert(activityUser);}

        采用jmeter测试,数据库限制活动报名人数50,jmeter设置1s请求100次模拟高并发测试:

        相比于无防护,并没有超卖问题出现。

五、一人一单业务问题解决示例

业务说明:继续采用上述业务场景,超卖问题已经解决,但是仍存在一个用户多次报名问题,因此采用悲观锁策略,也就是采用redisson的分布式锁来解决业务问题。

        为防止在锁的执行时间内,有其余线程等待锁并在锁释放后获取锁再次执行业务,因此在锁内仍需添加双重检查机制。

/*** 活动报名 - 超卖、一人一单问题解决*/@Transactional(rollbackFor = Exception.class)@Overridepublic void registerActivity(Long activityId, Long userId) {// 1. 先检查用户是否已报名LambdaQueryWrapper<ActivityUser> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(ActivityUser::getActivityId, activityId).eq(ActivityUser::getUserId, userId);Long count = activityUserMapper.selectCount(queryWrapper);if (count > 0) {throw new ActivityException("用户已报名");}// 2. 构建用户报名分布式锁keyString userActivityLockKey = "lock:user:activity:" + userId + ":" + activityId;RLock userActivityLock = redissonClient.getLock(userActivityLockKey);try {// 3. 尝试获取锁boolean isLocked = userActivityLock.tryLock(3, 10, TimeUnit.SECONDS);if (!isLocked) {throw new ActivityException("系统繁忙,请稍后重试");}// 4. 获取锁后再次检查用户是否已报名(双重检查)count = activityUserMapper.selectCount(queryWrapper);if (count > 0) {throw new ActivityException("用户已报名");}// 5. 查询活动信息Activity activity = baseMapper.selectById(activityId);if (activity == null) {throw new ActivityException("活动不存在");}// 6. 检查活动状态是否为已审核if (!StatusEnum.approved.getCode().equals(activity.getStatus())) {throw new ActivityException("活动未审核通过,无法报名");}// 7. 检查人数限制if (activity.getParticipantCount() >= activity.getParticipantLimit()) {throw new ActivityException("活动已报满");}// 8. 更新活动报名人数(乐观锁解决并发超卖问题)LambdaUpdateWrapper<Activity> updateWrapper = new LambdaUpdateWrapper<>();updateWrapper.eq(Activity::getActivityId, activityId).lt(Activity::getParticipantCount, activity.getParticipantLimit()).setSql("participant_count = participant_count + 1");int update = baseMapper.update(updateWrapper);if (update == 0) {throw new ActivityException("活动已报满");}// 9. 记录报名信息ActivityUser activityUser = ActivityUser.builder().activityId(activityId).userId(userId).build();activityUserMapper.insert(activityUser);} catch (InterruptedException e) {Thread.currentThread().interrupt();throw new ActivityException("系统繁忙,请稍后重试");} finally {// 10. 释放锁if (userActivityLock.isHeldByCurrentThread()) {userActivityLock.unlock();}}}

        继续采用原来的jmeter测试:对于同一位用户只有第一次报名成功,其他均失败。

http://www.dtcms.com/a/580027.html

相关文章:

  • 怎么套用网站模板轻量云做网站怎么样
  • 青海网站建设公司哪家好网站建设与维护模板
  • 网站建设先进个人西安企业网站建设模板
  • 广西学校论坛网站建设加强部门网站建设工作
  • 网站服务合同范本文创产品设计分析
  • 莆田网站制作公司韩国男女直接做的视频网站
  • 网站首页列表布局设计沪上家居装修官网
  • seo网站托管徐汇网站制作设计
  • 企业自建网站有哪些绍兴seo排名公司
  • 威海城乡建设局网站做网站最少几个页面
  • 陇南市建设局网站wordpress站点取名
  • 学校为什么要做网站可以做雷达图的网站
  • 营销类网站推荐自助建站 平台
  • 最版网站建设案例北京网络职业技术学院官网
  • 网站是别人做的域名自己怎么续费网站后台首页
  • php和c 做网站的区别wordpress卖
  • 制作网站设计的技术有郴州新网招聘
  • 网站代付系统怎么做设计包装公司
  • 浙江电商网站建设销售wordpress文章阅读量
  • 提升审美网站c#网站开发模板
  • 90设计网站几次是什么意思用护卫神做共享网站
  • 网站建设的一般流程邯郸网站设计公司
  • 广东建设公司网站郑州网站关
  • 做火锅加盟哪个网站好网站专题制作教程
  • 网站在手机上内页图不显示网站将要准备建设的内容有哪些
  • php5 mysql网站开发实例精讲温州市建设工程质量监督站网站
  • 石家庄住房和城乡建设部网站51星变网页游戏官网
  • dede 网站根目录网站建设属于什么部门
  • 自己做的网站是怎么赚钱吗公司内部网站系统
  • wordpress 批量建站哪些网站平台可以做推广