《Java高并发秒杀API》知识总结

最近几天看了这个项目《Java高并发秒杀API》,目前除了高并发知识没有涉及到,关于Dao层,service层,Web层,以及前端交互界面都有涉及。整个项目就是平常我们看到的秒杀界面,包含用户登录手机号,查看商品列表,查看商品秒杀状态,以及执行秒杀和秒杀后的结果反馈!

下面具体看一看每一层的功能。

Dao层

Dao层主要是两个接口的设计

  • 接口1:秒杀接口的设计
  1. 减少库存
  2. 根据id来查询秒杀商品对象
  3. 根据偏移量查询秒杀商品列表页
  • 接口2:秒杀成功对象接口的设计
  1. 插入购买明细
  2. 根据独有的id和userPhone查询秒杀成功的对象并携带秒杀商品的信息(因为多个商品的信息会对应一个人)

具体接口功能的实现用的是mybatis框架来实现,主要是可以自己控制sql语句的编写,达到想要的数据输出,建立相应的xml文件,编写实现功能的sql语句。

首先是配置mybatis-config.xml全局配置文件

<configuration>
	<!-- 配置全局属性 -->
	<settings>
		<!-- 使用jdbc的getGeneratedKey获取数据库自增主键值 -->
		<setting name="useGeneratedKeys" value="true"/>
		<!-- 使用列别名替换列名 -->
		<setting name="useColumnLabel" value="true"/>
		<!-- 使用驼峰命名法 -->
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>
</configuration>

spring-dao.xml的配置,这里用的是c3p0连接池,可以人为的设定属性参数

具体配置步骤如下:

 <!-- 配置整合mybatis过程 -->
        <!-- 数据库连接池相关参数properties属性 -->
        <context:property-placeholder location="classpath:jdbc.properties"/>
        <!-- 数据库的连接池 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        	<property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
        	<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/seckill?serverTimezone=UTC"></property>
        	<property name="user" value="root"></property>
        	<property name="password" value="******"></property>
        	 
        	<!-- c3p0连接池的私有属性 -->
        	<property name="maxPoolSize" value="30"></property>
        	<property name="minPoolSize" value="5"></property>
        	<!-- 关闭连接后不自动commit -->
        	<property name="autoCommitOnClose" value="false"></property>
        	<!-- 获取当前超时时间 -->
        	<property name="checkoutTimeout" value="1000"></property>
        	<!-- 当获取连接失败尝试次数 -->
        	<property name="acquireRetryAttempts" value="2"></property>
        </bean>
        
        <!-- 配置SqlSessionFactory -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        	<!-- 注入数据库连接池 -->
        	<property name="dataSource" ref="dataSource"></property>
        	<!-- 配置mybatis-config.xml全局配置  -->
        	<property name="configLocation" value="classpath:mybatis-config.xml"></property>
       		<!-- 扫描entity 别名设置 --> 	
       		<property name="typeAliasesPackage" value="com.duanxicao.entity"></property>
       		<!-- 需要扫描mapper需要的xml文件 -->
       		<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
        </bean>
        <!-- 配置扫描Dao接口包,动态实现dao接口,注入到spring容器中 -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        	<!-- 给出需要扫描的Dao接口 -->
        	<property name="basePackage" value="com.duanxicao.dao"></property>
        	<!-- 注入sqlSessionFactory -->
        	<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
        </bean>

Service层

service主要是实现给用户的接口(需要站在用户使用的角度上设计接口)

  • 查询所有的秒杀记录
  • 查询单个的秒杀记录
  • 秒杀开启输出秒杀地址,否则输出系统时间,告诉用户还需等待多久
  1. 运用了dto,数据传输对象的模式,传入参数,让具体的传输类做处理,最后返回我们所需要的数据
  2. 这里用到的是接口暴露的传输类,简称exposer类,主要是包含是否开启秒杀的判断,MD5加密值,以及秒杀对象商品id,当前时间,秒杀开启时间,秒杀结束时间。通过设定不同的构造方法,实现不同的处理,得到不同情况的不同结果
  • 执行秒杀操作(这里需要设定秒杀过程中可能产生的异常,用exception包中的相关异常类接收并处理)
  1. 这里运用传输类execution执行操作,判断用户秒杀状态,以及执行后的具体完成的消息,并反馈

编写实现类impl

开启秒杀地址实现方法:

先通过商品id查询到商品对象,如果商品对象为null,回传给数据传输对象失败+商品id的数据,若不为空,则获取当前系统时间,与对应商品秒杀开启时间和结束时间做一个对比,时间不符合,则回传响应的false+id+startTime+endTime,否则则是成功,此时生成md5,传入true+md5+id

执行秒杀操作:

先判断暴露接口中md5值与获得的md5值是否相等,不相等的话,则数据被篡改,抛出异常。否则获取当前时间,完成减库存的操作,若减库存成功,则完成插入秒杀成功明细操作,若插入明细不成功,由于设定了手机号为唯一的值,则说明重复秒杀,抛出异常,否则则说明成功此时获取到成功秒杀对象,传入数据传输类中做具体处理。

spring-service.xml配置

<!-- 扫描service包下使用注解的类型 -->
        <context:component-scan base-package="com.duanxicao.service"></context:component-scan>
        <!-- 配置事务管理器 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        	<!-- 注入数据库连接池 -->
        	<property name="dataSource" ref="dataSource"></property>
        </bean>  
        <!-- 配置基于注解的声明式事务
        	默认使用注解来管理事务行为
         -->
        <tx:annotation-driven transaction-manager="transactionManager"/>

Web层

web层主要是通过注解的方式来完成相应的数据操作,

  • 具体明细(所有秒杀shangpin)
  • 相关细节(伴随秒杀商品id)
  • 暴露秒杀接口(具体商品id)
  • 执行秒杀操作
  • 获取系统当前时间

spring-web.xml配置

<!-- 配置SpringMVC -->
        <!-- 1:开启SpringMVC注解模式 -->
        <!-- 简化配置
        	1.自动注册DefaultAnnotationHandlerMapping,DefaultAnnotationHandlerAdapter
        	2.提供一系列的数据绑定:数字和日期格式
        	xml,json默认读写的支持
         -->
        <mvc:annotation-driven></mvc:annotation-driven>
        
        <!-- 2:开启对静态资源的支持配置
        	1.加入对静态资源的处理
        	2.允许使用“/"做映射
         -->
        <mvc:default-servlet-handler/>
        <!-- <mvc:resources location="/js/" mapping="/js/**"></mvc:resources> -->
        
        <!-- 配置jsp,显示viewResolver -->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        	<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
        	<property name="prefix" value="/WEB-INF/jsp/"></property>
        	<property name="suffix" value=".jsp"></property>
        </bean>
        
        <!-- 扫描web相关的bean -->
        <context:component-scan base-package="com.duanxicao.web"></context:component-scan>

最后就是前后端交互界面了。

注:SpringMVC运行过程

  1. 客户端(浏览器)发送请求,直接请求到DispatcherServlet,
  2. DispathcerServlet根据请求信息调用HandlerMapping,DefaultAnnotationHandlerMapping解析请求对象的handler,
  3. 解析到对应的Handler之后,HandlerAdapter调用组件DefaultAnnotationHandlerAdapter适配器做处理
  4. 处理调用Controller中的HandlerMethod方法,当HandlerMethod执行完成之后,会返回一个ModelAndView,
  5. viewResolver会根据逻辑对view进行视图解析,解析之后调用.jsp对应的.class文件并运行,得到结果
  6. 最后把运行的.class文件的结果响应给客户端,以上就是SpringMVC运行原理

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值