前言

该篇主要实现秒杀业务层,秒杀业务逻辑里主要包括暴露秒杀接口地址、实现秒杀业务逻辑。同时声明了三个业务类:Exposer、SeckillExecution、SeckillResult。 Exposer主要用来实现暴露接口时一个md5的加密,防止用户在客户端篡改数据。根据seckillid生成md5,提交秒杀请求时会根据这个md5和seckillid比对是否是合法的请求。SeckillExecution主要封装秒杀时的返回值。

SeckillExecution有2个属性,state、stateinfo,这里我没有封装枚举值,还是用整型和字符串给客户端传值,在Service里看着也直观些。

准备工作

1、spring-service.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" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--1、注解包扫描-->
<context:component-scan base-package="com.seckill.service"/> <!--2、配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据库-->
<property name="dataSource" ref="dataSource"/>
</bean> <!--3、配置基于注解的声明式事务-->
<tx:annotation-driven transaction-manager="transactionManager"/> </beans>

实现秒杀业务

秒杀相关的关键方法就是最后两个方法,一个是对外暴漏秒杀地址,一个是秒杀方法。

public interface SeckillService {

    List<Seckill> getSeckillList();

    Seckill getById(long seckillId);

    /**对外暴漏秒杀接口**/
Exposer exposeSeckillUrl(long seckillId); /**
* 执行秒杀操作,有可能成功,有可能失败,所以这里我们抛出自自定义异常
* ***/
SeckillExecution executeSeckill(long seckillId,long phone,String md5) throws SeckillException,
RepeatKillException,
SeckillCloseException; }

  

@Service
public class SeckillServiceImpl implements SeckillService { /***
* 秒杀行为的枚举放在这里说明
* 1、 秒杀成功
* 0、 秒杀结束
* -1、重复秒杀
* -2、系统异常
* -3、数据篡改
* ***/ private Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired
SeckillDao seckillDao; @Autowired
SuccessKillDao successKillDao; private String salt = "zhangfei"; @Override
public List<Seckill> getSeckillList() {
return seckillDao.queryAll(0, 100);
} @Override
public Seckill getById(long seckillId) {
return seckillDao.queryById(seckillId);
} @Override
public Exposer exposeSeckillUrl(long seckillId) {
Seckill seckill = getById(seckillId); Date startTime = seckill.getStartTime();
Date endTime = seckill.getEndTime(); Date now = new Date(); if (now.getTime() < startTime.getTime() || now.getTime() > endTime.getTime()) {
return new Exposer(false, seckillId, startTime.getTime(), endTime.getTime(), now.getTime());
} String md5 = getMd5(seckillId); return new Exposer(true, md5, seckillId);
} @Override
@Transactional
public SeckillExecution executeSeckill(long seckillId, long phone, String md5)
throws SeckillException,RepeatKillException,SeckillCloseException { if (md5 == null || !md5.equals(getMd5(seckillId))) {
throw new SeckillException("非法请求");
} Date now = new Date(); try {
int insertCount = successKillDao.insertSuccessKilled(seckillId, phone);
if (insertCount <= 0) {
throw new RepeatKillException("重复秒杀"); } else {
int updateCount = seckillDao.reduceNumber(seckillId, now);
if (updateCount <= 0) {
throw new SeckillCloseException("秒杀已关闭");
} else {
//秒杀成功,可以把秒杀详情和商品详情实体返回
SuccessKilled successKilled = successKillDao.queryByIdWithSeckill(seckillId, phone);
return new SeckillExecution(seckillId, 1, "秒杀成功", successKilled);
}
} } catch (SeckillCloseException e) {
throw e;
} catch (RepeatKillException e1) {
throw e1;
} catch (SeckillException e2) {
logger.error(e2.getMessage(), e2);
throw new SeckillException("Unkonwn error:" + e2.getMessage());
} } private String getMd5(long seckillId) {
String base = seckillId + "/" + salt;
String md5 = DigestUtils.md5DigestAsHex(base.getBytes()); return md5; }
}

  

基于SpringMVC+Spring+MyBatis实现秒杀系统【业务逻辑】的更多相关文章

  1. 基于SpringMVC+Spring+MyBatis实现秒杀系统【客户端交互】

    前言 该篇主要实现客户端和服务的交互.在第一篇概况里我已经贴出了业务场景的交互图片. 客户端交互主要放在seckill.js里来实现.页面展现基于jsp+jstl来实现. 准备工作 1.配置web.x ...

  2. 基于SpringMVC+Spring+MyBatis实现秒杀系统【概况】

    前言 本教程使用SpringMVC+Spring+MyBatis+MySQL实现一个秒杀系统.教程素材来自慕课网视频教程[https://www.imooc.com/learn/631].有感兴趣的可 ...

  3. 基于SpringMVC+Spring+MyBatis实现秒杀系统【数据库接口】

    前言 该篇教程主要关注MyBatis实现底层的接口,把MyBatis交给Spring来托管.数据库连接池用的c3p0.数据库用的MySQL.主要有2个大类:秒杀商品的查询.秒杀明细的插入. 准备工作 ...

  4. 手把手教你使用VUE+SpringMVC+Spring+Mybatis+Maven构建属于你自己的电商系统之vue后台前端框架搭建——猿实战01

            猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是 ...

  5. 第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第十天】(单点登录系统实现)

    https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...

  6. 第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第十二天】(系统架构讲解、nginx)

    https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...

  7. Idea SpringMVC+Spring+MyBatis+Maven调整【转】

    Idea SpringMVC+Spring+MyBatis+Maven整合   创建项目 File-New Project 选中左侧的Maven,选中右侧上方的Create from archetyp ...

  8. SpringMVC+Spring+MyBatis+Maven调整【转】

    Idea SpringMVC+Spring+MyBatis+Maven整合   创建项目 File-New Project 选中左侧的Maven,选中右侧上方的Create from archetyp ...

  9. 第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第八天】(solr服务器搭建、搜索功能实现)

    https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...

随机推荐

  1. IE控件cab包手动安装

    一.XP系统 第1步:先解压cab包,在解压的文件中找到*.inf文件,然后右击,选择安装,此时会把解压文件拷到C:Windows\System32文件夹下.第2步:注册拷到上述文件夹下的ocx文件. ...

  2. 用gulp-imageisux智图api压缩图片

    ➣ 智图平台是什么? 智图是腾讯ISUX前端团队开发的一个专门用于图片压缩和图片格式转换的平台,其功能包括针对png,jpeg,gif等各类格式图片的压缩,以及为上传图片自动选择最优的图片格式.同时, ...

  3. 弄懂CNN,然后提升准确率4.21-4.27

    英语: 1.每天背单词,75起步.(这周没怎么背,考虑调整了) 2.并背王江涛图画作文一:传统文化(这周没背,但肯定要做) 学校: 0.吴恩达ML 1.毕设一:可视化,肺癌基因突变,深度学习(那么作图 ...

  4. VS启动Winform项目提示:不支持互操作调试

    64 位平台不支持互操作调试(托管 + 非托管混合模式调试). 在VS中设置项目属性--->调试--->取消选中“启用本地代码调试”. 此问题在.NET FrameWork低版本框架会出现 ...

  5. Django 简单的使用

    1.创建一个名字为 two 的项目 并 进入项目 2.创建一个 app 3.更改语言和时间 4,注册APP 5.模板创建和设置 设置模板查找的路径 6,然后我们开始设置 路由映射 主项目映射 然后我们 ...

  6. JDK、JRE

    JRE: java Runtime environment (java运行环境) JVM:java virtual machine (java 虚拟机) java程序就在jvm中运行. JDK: ja ...

  7. [Swift]LeetCode151. 翻转字符串里的单词 | Reverse Words in a String

    Given an input string, reverse the string word by word. Example: Input: "the sky is blue", ...

  8. [Swift]LeetCode280. 摆动排序 $ Wiggle Sort

    Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] < ...

  9. [Swift]LeetCode858. 镜面反射 | Mirror Reflection

    There is a special square room with mirrors on each of the four walls.  Except for the southwest cor ...

  10. [Swift]LeetCode882. 细分图中的可到达结点 | Reachable Nodes In Subdivided Graph

    Starting with an undirected graph (the "original graph") with nodes from 0 to N-1, subdivi ...