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

旅游网站建设经济评价分类信息网站建设方案

旅游网站建设经济评价,分类信息网站建设方案,手机网页编程,自己的网络平台怎么做1. 库存超卖问题重现 下面这段代码在多线程下存在线程安全问题! 超卖的主要原因是下面的步骤不是原子性的。 判断库存是否充足。库存扣减 public String deductProduct(String userId) {int stock Integer.parseInt(stringRedisTemplate.opsForValue().get(&quo…

1. 库存超卖问题重现

下面这段代码在多线程下存在线程安全问题!
超卖的主要原因是下面的步骤不是原子性的。

  1. 判断库存是否充足。
  2. 库存扣减
public String deductProduct(String userId) {int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));log.info("开始扣减库存");//加锁,分布式锁if (stock > 0) {int stockAfterDeduction = stock - 1;stringRedisTemplate.opsForValue().set("stock", String.valueOf(stockAfterDeduction));log.info("扣减库存成功,现库存为 {}", stockAfterDeduction);} else {log.error("库存不足,现库存为:{}", stock);}return "操作成功!";
}

==> 单机情况下,可以加锁(synchronized | ReentrantLock)解决这个线程安全问题。


但是在分布式场景下,必须使用分布式锁解决这个问题。

2. 手写简单分布式锁

set key value nx ex

2.1 可以基于set nx ex实现一个简单的分布式锁

public interface ILock {/*** 尝试获取锁* @param timeoutSecond 锁持有的超时时间,过期后自动删除* @return 是否加锁成功*/boolean tryLock(long timeoutSecond);/*** 释放锁*/void unLock();
}

2.2 分布式锁-实现加锁和解锁流程

public class SimpleRedisLock implements ILock {private static final String KEY_PREFIX = "lock:";//分布式中,集群的标识符uuid,用于表示集群中的每个节点private static final String ID_PREFIX = UUID.randomUUID().toString(true) + ":";//解锁的lua脚本,用于防止锁误删private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;private final String name; //锁的名字private final StringRedisTemplate stringRedisTemplate;public SimpleRedisLock(String name, StringRedisTemplate stringRedisTemplate) {this.name = name;this.stringRedisTemplate = stringRedisTemplate;}static {//初始化 unlock.lua脚本文件UNLOCK_SCRIPT = new DefaultRedisScript<>();UNLOCK_SCRIPT.setLocation(new ClassPathResource("unlock.lua"));UNLOCK_SCRIPT.setResultType(Long.TYPE);}@Overridepublic boolean tryLock(long timeoutSecond) {//获取线程标识,uuid + thread-idString threadId = ID_PREFIX + Thread.currentThread().getId();Boolean isLock = stringRedisTemplate.opsForValue()//基于set nx ex实现分布式锁.setIfAbsent(KEY_PREFIX + name, threadId, timeoutSecond, TimeUnit.SECONDS);return Boolean.TRUE.equals(isLock);}@Overridepublic void unLock() {//删除锁,要防止锁误删(lua脚本)stringRedisTemplate.execute(UNLOCK_SCRIPT,Collections.singletonList(KEY_PREFIX + name),ID_PREFIX + Thread.currentThread().getId());}
}

2.3 lua脚本实现

if (redis.call('get', KEYS[1]) == ARGV[1])
then-- 一致的话,就删除锁return redis.call('del', KEYS[1])
end

2.4 分布式锁实战

public String deductProduct(@PathVariable String userId) {ILock lock = new SimpleRedisLock("product", stringRedisTemplate);//尝试加锁boolean isLock = lock.tryLock(60);if (!isLock) {log.error("线程加锁失败: {}", Thread.currentThread().getId());return "加锁失败";}try {int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));log.info("开始扣减库存");if (stock > 0) {int stockAfterDeduction = stock - 1;stringRedisTemplate.opsForValue().set("stock", String.valueOf(stockAfterDeduction));log.info("扣减库存成功,现库存为 {}", stockAfterDeduction);} else {log.error("库存不足,现库存为:{}", stock);}return "操作成功!";}finally {lock.unLock();}
}

3. Redisson框架

uuid(区分不同的jvm服务)+线程id(区分jvm服务上面的线程)

3.1 导入pom坐标

<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.13.6</version>
</dependency>

3.2 配置Redisson客户端

@Configuration
public class RedissonConfig {@Value("${spring.redis.host}")public String host;@Value("${spring.redis.port}")public String port;@Value("${spring.redis.password}")private String password;@Beanpublic RedissonClient redissonClient() {// 单机redis配置Config config = new Config();String redisAddress = "redis://" + host + ":" + port;config.useSingleServer().setAddress(redisAddress).setPassword(password);// 设置分布式锁 watch dog超时时间// config.setLockWatchdogTimeout()return Redisson.create(config);}
}

3.3 使用分布式锁

public class HelloController {private RedissonClient redissonClient;public String deductProduct(String userId) {//获取分布式锁的锁对象RLock lock = redissonClient.getLock("product");//加分布式锁lock.lock(); //set nx ex 30stry {//业务逻辑}finally {//释放锁lock.unlock();}}
}

3.4 Redission源码分析

在这里插入图片描述

3.5 Redis主从架构下,分布式锁失效

Redis的集群架构保证AP,Zookeeper的集群架构保证CP。
但是Redis在主从情况下会出现锁丢失的问题,如何解决呢? => 红锁RedLock
在这里插入图片描述

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

相关文章:

  • 亚运村网站建设免费高清视频素材app哪里找
  • 网站修改了关键词被降权软件开发前端和后端区别
  • 做网站必须在工信部备案吗网站与装修公司
  • 苏州网站建设有限公司都江堰网站建设公司
  • 杭州网站建设哪家强网站建设 推广薪资
  • 个人网站备案出现公司名字怎么办社区推广怎么做
  • 【解决办法】网络训练报错AttributeError: module ‘jax.core‘ has no attribute ‘Shape‘.
  • 商城网站开发培训学校网站推荐正能量
  • 帮助做问卷调查的网站视频网站开发流程图
  • 网站建设分金手指排名十一网站与客户端的区别吗
  • 汕头网站建设系统移动端网站的重要性
  • 招商网站有哪些外国人做的汉字网站
  • 集团公司网站案例网站建设 云计算
  • 天津建设科技杂志的官方网站中铁三局招聘文员要求身材好
  • 网站站长如何赚钱WordPress料神
  • 黄岩做网站公司电话网站图片上的水印怎么做
  • 后端网站开发遇到的难题解决网站你懂我意思正能量晚上在线观看不用下载免费魅族
  • 地区网站建设html网页制作代码模板
  • 网站解析教程影视网络推广方案
  • 网站开发师是属于IT主体职业网站美工如何做
  • 网站后台上传软件免费的微网站哪个好
  • 网站建设的网站定位上海设计公司官网
  • 专业网站建设流程网站建设赛车
  • 网站域名域名wordpress兼容php版本
  • 婚纱摄影网站开题报告一起做网站女装夏季
  • 建设银行内部网站6攀枝花建设银行网站
  • 个人网站 域名选择浙江微信网站建设
  • 网站头部修改东莞人才市场招聘官网
  • 中国建设银行网站登陆做空运货代常用网站
  • 手机适配网站深圳市在建项目查询