在idea中高并发下的分布式锁以及解决方法

案例:1.互联网秒杀   2.抢优惠卷   3.接口幂

引入pom文件

 <packaging>war</packaging><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.8.RELEASE</version></dependency><!-- 实现分布式锁的工具类 --><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.17.7</version></dependency><!-- Spring操作Redis的工具类 --><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>2.3.2.RELEASE</version></dependency><!-- Redis客户端 --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.9.0</version></dependency><!-- JSON解析工具 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.4</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><configuration><port>8001</port><!-- /表示访问应用的路径,省略项目名 --><path>/</path><!-- 配置编码方式为UTF-8 --><uriEncoding>UTF-8</uriEncoding></configuration><executions><execution><!-- 打包完成后,运行服务 --><phase>package</phase><goals><goal>run</goal></goals></execution></executions></plugin></plugins></build>

我们在pom文件中配置了打包后运行的jar包,所以我们要改变启动方式

 

在resources下创还能spring.xml的配置类

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation=" http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.leq"/><!--  配置Redis连接工厂对象--><bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"><property name="hostName" value="192.168.40.100"></property><property name="port" value="6379"></property></bean><!--  Spring框架为了简化Redis操作提供了一个Redis操作的模板类:RedisTemplate--><bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"><!--ref表示该属性的取值是引用类型,将ref取值设置为外部bean的id值--><property name="connectionFactory" ref="connectionFactory"></property></bean></beans>

 配置web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/spring.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 配置解决中⽂乱码问题。此过滤器会进⾏:request.setCharacterEncoding("utf-8") --><filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
</web-app>

抢购的业务:

   @Autowired//简化Redis操作的模板类private StringRedisTemplate stringRedisTemplate;@RequestMapping("seckill")public synchronized String secKill(){String phone_count = stringRedisTemplate.opsForValue().get("phone_count");int phoneCount = Integer.parseInt(phone_count);if(phoneCount>0){//给redis中的数据添加锁  setnx()  在key不存在时,设置值phoneCount--;stringRedisTemplate.opsForValue().set("phone_count",String.valueOf(phoneCount));System.out.println("当前库存数量:"+phoneCount);}else {System.out.println("手机库存不足...");}return "当前的手机数量:"+phoneCount;} 

在一次性涌入大量数据的时候可能会出现-1或者同票的情况,这个时候就需要加锁 

  //RedissonClient实现分布式锁@Autowiredprivate RedissonClient redisson;@RequestMapping("seckill")public synchronized String secKill(){//获取开发者自定义的锁RLock redissonLock = redisson.getLock("phone");//加锁,添加过期时间       1过期时间       2具体的单位    后面的代码都是受保护的redissonLock.lock(30, TimeUnit.SECONDS);Integer phoneCount = null;try {//高并发抢购业务String phone_count = stringRedisTemplate.opsForValue().get("phone_count");phoneCount = Integer.parseInt(phone_count);if(phoneCount>0){//给redis中的数据添加锁  setnx()  在key不存在时,设置值phoneCount--;stringRedisTemplate.opsForValue().set("phone_count",String.valueOf(phoneCount));System.out.println("当前库存数量-1:"+phoneCount);}else {System.out.println("手机库存不足...");}}catch (Exception e){System.out.println("有异常");}finally {redissonLock.unlock();//释放锁   释放后代码不受保护}return "当前的手机数量:"+phoneCount;}

 模拟一次性涌入大量数据:   

        1.打开ApiPost测试工具

        2.新建一个接口,访问刚刚写的seckil接口,点击保存

        3.保存后点击自动化测试,新建一个测试用例,点击最左边的HTTP请求接口,选择刚刚建的接口,在上面可以选择次数和时间,然后点击执行即可

      4.执行的结果如下,库存的数量需要我们自己手动在redis库中进行设置 :set phone_count 10

 

 

      

解决高并发就需要一个配置类RedissonConfig

//分布式锁的配置类import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//分布式锁配置类
@Configuration
public class RedissonConfig {//1.Redis单机模式下@Bean  //RedissonClient 是Redisson客户端对象,使用该对象来添加锁public RedissonClient singletonModelRedisson(){Config config =new Config();//构建Redis结构的配置//  Redis数据库默认放在字库1中,对应的下标为0config.useSingleServer().setAddress("redis://192.168.40.100:6379").setDatabase(0);return Redisson.create(config);}/*  // 2.Redis集群@Beanpublic RedissonClient clusterModelRedisson() {Config config =new Config();//构建Redis结构的配置config.useClusterServers().setScanInterval(2000)//集群的扫描时间.addNodeAddress("redis://192.168.40.100:6379","redis://192.168.40.101:6379","redis://192.168.40.102:6379");return Redisson.create(config);}//3.Redis集群:主从架构@Beanpublic RedissonClient masterModelRedisson() {Config config =new Config();//构建Redis结构的配置config.useMasterSlaveServers().setMasterAddress("redis://192.168.40.100:6379").addSlaveAddress("redis://192.168.40.101:6379","redis://192.168.40.102:6379");return Redisson.create(config);}@Bean//4Redis集群:哨兵模式public RedissonClient sentinelModelRedisson() {Config config =new Config();//构建Redis结构的配置config.useSentinelServers().addSentinelAddress("redis://192.168.40.101:6379","redis://192.168.40.102:6379","redis://192.168.40.100:6379");return Redisson.create(config);}
*/
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/5217.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 基本数据类型(三)

文章目录 每日一句正能量数值运算数值类型实例String&#xff08;字符串&#xff09; 每日一句正能量 人的相处&#xff0c;靠的是真心&#xff0c;不是套路。合得来的人&#xff0c;坦诚相待&#xff0c;合不来的人&#xff0c;客气寒暄&#xff1b;谁也别给谁冷脸看&#xff…

自然语言处理从入门到应用——预训练模型总览:迁移学习与微调

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 相关文章&#xff1a; 预训练模型总览&#xff1a;从宏观视角了解预训练模型 预训练模型总览&#xff1a;词嵌入的两大范式 预训练模型总览&#xff1a;两大任务类型 预训练模型总览&#xff1a;预训练模型的拓展 …

【夜深人静学数据结构与算法】回溯算法

目录 前言&#xff1a; 回溯算法&#xff1a; 回溯法的常见应用: 回溯法的模板: 回溯法的图解&#xff1a;​ 案例&#xff1a; 77. 组合 - 力扣&#xff08;LeetCode&#xff09; 总结&#xff1a; 前言&#xff1a; 回溯算法是一个比较抽象的算法&#xff0c;因此我们…

基于Springboot+vue的垃圾分类网站设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

Transformer(四)--实现验证:transformer 机器翻译实践

转载请注明出处&#xff1a;https://blog.csdn.net/nocml/article/details/125711025 本系列传送门&#xff1a; Transformer(一)–论文翻译&#xff1a;Attention Is All You Need 中文版 Transformer(二)–论文理解&#xff1a;transformer 结构详解 Transformer(三)–论文实…

【Spring】Bean的作用域与生命周期详情:请简述Spring的执行流程并分析Bean的生命周期?

前言 我们都知道&#xff0c;Spring框架为开发人员提供了很多便捷&#xff0c;这使得开发人员能够更加专注于应用程序的核心业务逻辑&#xff0c;而不需要花费大量时间和精力在技术细节上。作为一个包含众多工具方法的IoC容器&#xff0c;存取JavaBean是其极为重要的一个环节。…

linux运维常用命令(持续更新)

目录 一&#xff1a; 查看指定端口是否被监听 二&#xff1a;查看某个端口/服务相关进程 三&#xff1a;在B机器查看是否可以访问A机器某个端口,查看端口是否开放 四&#xff1a;查看端口占用列表 五&#xff1a;查看端口占用情况 六&#xff1a;查看哪些进程监听了2181端…

OpenCV(加载、修改、保存图像)

目录 1、图像加载 2、显示图像 3、修改图像 4、图像保存 OpenCV官方文档查询地址&#xff1a;OpenCV: OpenCV modules 1、图像加载 加载图像&#xff08;用cv::imread )imread功能是加载图像文件成为一个Mat对象&#xff0c;其中第一个参数表示图像文件名称 第二个参数&…

Debian 环境使用 docker compose 部署 sentry

Debian 环境使用 docker compose 部署 sentry Sentry 简介什么是 Sentry &#xff1f;Sentry 开发语言及支持的 SDKSentry 功能架构 前置准备条件规格配置说明Docker Desktop 安装WSL2/Debian11 环境准备 Sentry 安装步骤docker 部署 sentry 步骤演示过程说明 卸载关闭 Sentry总…

数据库系统概论(三)数据库设计、数据库恢复技术、并发控制

作者的话 前言&#xff1a;总结下知识点&#xff0c;自己偶尔看一看。 一、数据库设计 数据库设计是指对于一个给定的应用环境&#xff0c;构造&#xff08;设计&#xff09;优化的数据库逻辑模式和物理结构&#xff0c;并据此建立数据库及其应用系统 1.1概述 1.1.1数据库设计…

C#winform吃棋子

实训内容: (1)设计 WinForm应用程序用于获取指定主机名的IP地址,结果如图8-12所示。 (2)编写一个可以通过因特网对弈的“吃棋子”游戏。 服务器可以同时服务多桌,每桌允许两个玩家通过因特网对弈。 2允许玩家自由选择坐在哪一桌的哪一方。如果两个 玩家坐在同一桌,双方应都能看…

PyQt5入门1——PyQt5的安装与Hello World应用

PyQt5入门1——PyQt5的安装与Hello World应用 学习前言简介&#xff08;From 百度百科&#xff09;安装Hello World1、窗口构建a、构建基础类b、编写UI 2、主程序运行 全部代码 学习前言 搞搞可视化界面哈&#xff0c;虽然不一定有用&#xff0c;但是搞一下。 简介&#xff…