Java秒杀简单设计四:service层设计
接上一篇 https://www.cnblogs.com/taiguyiba/p/9829191.html 封装了系统传递的数据类和异常类
本文继续设计service层设计:
1.SeckillService.java
package com.seckill.service; import java.util.List; import com.seckill.dto.Exposer;
import com.seckill.dto.SeckillExecution;
import com.seckill.entity.Seckill;
import com.seckill.exception.RepeatKillException;
import com.seckill.exception.SeckillCloseException;
import com.seckill.exception.SeckillException; /**
* 三个方面:1.方法定义的粒度,参数,返回类型(return ,类型/异常)
* @author kangjie
*
*/
public interface SeckillService { /**
*
* 查询所有秒杀记录
* @return
*/
List <Seckill> getSeckillList();
/**
*
* 查询单个秒杀记录
* @param seckillId
* @return
*/
Seckill getById(long seckillId);
/**
* 秒杀开启时输出秒杀接口地址 否则输出系统时间和秒杀时间
* @param seckillId
*/
Exposer exportSeckillUrl(long seckillId); //执行秒杀操作
SeckillExecution excuteSeckill(long seckillId,long userPhone,String md5)
throws RepeatKillException,SeckillCloseException,SeckillException; //执行秒杀操作by存储过程
SeckillExecution excuteSeckillProcedure(long seckillId,long userPhone,String md5);
}
2. SeckillServiceImpl
秒杀事务控制,在函数中如果更新出现问题,就会抛出异常,进行事务回滚。
package com.seckill.service.impl; import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils; import com.seckill.dao.SeckillDao;
import com.seckill.dao.SuccessKilledDao;
import com.seckill.dao.cache.RedisDao;
import com.seckill.dto.Exposer;
import com.seckill.dto.SeckillExecution;
import com.seckill.entity.Seckill;
import com.seckill.entity.SuccessKilled;
import com.seckill.enums.SeckillStateEnum;
import com.seckill.exception.RepeatKillException;
import com.seckill.exception.SeckillCloseException;
import com.seckill.exception.SeckillException;
import com.seckill.service.SeckillService; @Service
public class SeckillServiceImpl implements SeckillService { private Logger logger=LoggerFactory.getLogger(this.getClass()); @Autowired
private SeckillDao seckillDao;
@Autowired
private SuccessKilledDao successKilledDao;
@Autowired
private RedisDao redisDao;
//md5盐值,用于混淆md5
private final String salt = "!@#!@#!@#$ASDFASDFzxcv_|+)+)(("; @Override
public List<Seckill> getSeckillList() {
// TODO Auto-generated method stub
return seckillDao.queryAll(, );
} @Override
public Seckill getById(long seckillId) {
// TODO Auto-generated method stub
return seckillDao.queryById(seckillId);
} @Override
public Exposer exportSeckillUrl(long seckillId) {
// TODO Auto-generated method stub
//访问redis:缓存优化,超时的基础上维护一致性
Seckill seckill = redisDao.getSeckill(seckillId);
if(seckill == null) {
//访问数据库
seckill = seckillDao.queryById(seckillId);
if(seckill == null) {
return new Exposer(false, seckillId);
}else {
logger.error("放入redis中: " + seckill.toString());
redisDao.putSeckill(seckill);
}
}
Date startTime = seckill.getStartTime();
Date endTime = seckill.getEndTime();
Date nowTime = new Date();
if(nowTime.getTime() > endTime.getTime()
||nowTime.getTime() < startTime.getTime()) {
return new Exposer(false, nowTime.getTime(), startTime.getTime(), endTime.getTime(),seckillId);
}
String md5 = getMD5(seckillId);
return new Exposer(true, md5, seckillId); // return null;
}
private String getMD5(long seckillId) {
String base = seckillId + "/" + salt;
String md5 = DigestUtils.md5DigestAsHex(base.getBytes());
return md5;
} @Override
@Transactional
public SeckillExecution excuteSeckill(long seckillId, long userPhone, String md5)
throws RepeatKillException, SeckillCloseException, SeckillException {
// TODO Auto-generated method stub
if(md5 == null || !md5.equals(getMD5(seckillId))) {
throw new SeckillException("seckill data rewirte");
}
try { int insertCount = successKilledDao.insertSuccessKilled(seckillId, userPhone);
if (insertCount <= ) {
// 重复秒杀
throw new RepeatKillException("repeat seckill");
} else {
int updateCount = seckillDao.reduceNumber(seckillId, new Date());
if (updateCount <= ) {
throw new SeckillCloseException("seckill closed");
} else {
// 秒杀成功
SuccessKilled successKilled = successKilledDao.queryByIdWithSeckill(seckillId, userPhone);
return new SeckillExecution(seckillId,SeckillStateEnum.SUCCESSD, successKilled);
} }
} catch (RepeatKillException e) {
// TODO: handle exception
logger.error(e.getMessage(),e);
throw new RepeatKillException("repeat seckill");
}catch (SeckillCloseException e) {
// TODO: handle exception
logger.error(e.getMessage(),e);
throw new SeckillCloseException("seckill closed");
}catch (Exception e) {
logger.error(e.getMessage(), e);;
throw new SeckillException("Inner error: " + e.getMessage());
} } @Override
public SeckillExecution excuteSeckillProcedure(long seckillId, long userPhone, String md5){
// TODO Auto-generated method stub
if(md5 == null || !md5.equals(getMD5(seckillId))) {
return new SeckillExecution(seckillId,SeckillStateEnum.DATA_REWRITE);
}
Date killTime = new Date();
Map<String,Object> map = new HashMap<String,Object>();
map.put("seckillId", seckillId);
map.put("phone", userPhone);
map.put("killTime", killTime);
map.put("result", null);
try {
seckillDao.killByProcedure(map);
//获取result
int result = MapUtils.getInteger(map, "result",-);
if(result == ) {
SuccessKilled sk = successKilledDao.queryByIdWithSeckill(seckillId, userPhone);
return new SeckillExecution(seckillId,SeckillStateEnum.SUCCESSD,sk);
}else {
return new SeckillExecution(seckillId, SeckillStateEnum.stateOf(result));
}
} catch (Exception e) {
// TODO Auto-generated catch block
logger.error(e.getMessage(),e);
return new SeckillExecution(seckillId, SeckillStateEnum.INNER_ERROR);
}
} }
Java秒杀简单设计四:service层设计的更多相关文章
- Java秒杀简单设计二:数据库表和Dao层设计
Java秒杀简单设计二:数据库表Dao层设计 上一篇中搭建springboot项目环境和设计数据库表 https://www.cnblogs.com/taiguyiba/p/9791431.html ...
- Java秒杀简单设计一:搭建springboot环境
项目参考:慕课网 https://www.imooc.com/learn/587 Java秒杀 开发环境 JDK1.8.Maven.Mysql.Eclipse.SpringBoot2.0.5.myb ...
- Java秒杀简单设计三:数据封装类
上一篇https://www.cnblogs.com/taiguyiba/p/9828984.html 整合了数据库表和Dao层代码 这一篇继续设计数据封装类: 涉及到获取秒杀地址,查询,返回秒杀结果 ...
- Dao层和Service层设计
1.Dao接口层 public interface IBaseDao<T, ID extends Serializable>{ public abstract Serializable s ...
- Java秒杀实战 (四)JMeter压测
转自:https://blog.csdn.net/qq_41305266/article/details/81071278. 一.JMeter入门 下载链接 http://jmeter.apache. ...
- HTML5学习+javascript学习:打飞机游戏Service层Control层+源码
2.Service层 如前所述,Service层是Control层与Model层之间桥接的一层,它拥有所有要在屏幕上显示的实体(除了背景)的引用 我们知道,当游戏运行时,随时都可能发生碰撞,随时都可能 ...
- SSM实战——秒杀系统之Service层接口设计与实现、Spring托管、声明式事务
一:Service层接口设计 准备工作:新建三个包:service包.exception包.dto包,分别用来存放业务接口.自定义异常类.dto类. 1:定义接口 package org.myseck ...
- Java高并发秒杀API之Service层
Java高并发秒杀API之Service层 第1章 秒杀业务接口设计与实现 1.1service层开发之前的说明 开始Service层的编码之前,我们首先需要进行Dao层编码之后的思考:在Dao层我们 ...
- [转]java web简单权限管理设计
原文地址:http://blog.csdn.net/zwx19921215/article/details/44467099 最近在做一个网站类型项目,主要负责后台,ui框架选型为jquery eas ...
随机推荐
- VCL 中的 Windows API 函数(4): AdjustWindowRectEx
AdjustWindowRectEx 用在了 Forms.DBCtrls 单元. AdjustWindowRectEx 可以根据窗口样式获取的边缘尺寸. 测试: var R: TRect; beg ...
- 找不到 android-support-v4 解决办法
Project->properties->Java Build Path->Libraries->Add External Jars中加入sdk目录下的extras/andro ...
- Yslow-23条军规
YslowYahoo发布的一款基于FireFox的插件,主要是为了提高网页性能而设计的,下面是它提倡了23条规则,还是很不错的,分享一下: 1.减少HTTP请求次数 合并图片.CSS.JS,改进首次访 ...
- Phpcms V9手机门户设置教程:怎么用PC V9做手机网站
一.在PHPcms V9管理后台设置手机门户 1.1.开启手机网站.位置:模块 >手机门户 > 添加手机站点,具体设置可参照截图: 填写站点名和LOGO文件相对位置,绑定用于手机网站的二级 ...
- numpy和Matplotlib篇---2
原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/ 5.3 Python的科学计算包 - Numpy numpy(Numerical Python ...
- Windows 7 无密码文件共享
Windows7中创建无密码的文件共享的几个步骤: 在“控制面板\所有控制面板项\网络和共享中心\高级共享设置”开启“关闭密码保护共享”和“启用文件和打印机共享”.关闭密码保护共享的操作会启用Gues ...
- [AX]AX2012 R2 HR Jobs, Positions, Department和Workers
部门.作业(Job的官方翻译)和位置(Position的官方翻译)是AX人力资源管理的基本组织元素,Job和Position在AX有的地方又称作工作和职位,其实这个翻译更为恰当. Job定义的是一个工 ...
- vux ajax请求 及 跨域
1)使用 AjaxPlugin 插件(在组件里使用) 引入插件 import { AjaxPlugin } from 'vux' 初始化 export default { components: { ...
- 【RF库Collections测试】Remove Values From List
Name:Remove Values From ListSource:Collections <test library>Arguments:[ list_ | *values ]Remo ...
- CentOS7安装ipython
python版本:2.7.5 yum install -y python2-pip.noarchyum install -y python-develpip install ipython==5.4. ...