Java之秒杀活动解决方案
引言
本文主要描述,服务端做相关秒杀活动的时候,对应的解决方案,即高并发下的数据安全。
优化方案
乐观锁思路
Redis中的watch,请求时,通过Redis查询当前抢购数据,如果当前抢购数据已经到达临界值,则直接提示相应的页面/信息,如返回已抢购完的页面。
分布式限流
当然,对于很大量的秒杀,可以准备多个Redis实例,用户请求时,可以随机数或者散列取模,找对应实例来进行抢购。
采用Redis有一个好处,比如支持很多应用服务器一起抢……
提高吞吐量
Nigix反向代理+负载均衡
实现流程
其实抛开秒杀这个场景来说正常的一个下单流程可以简单分为以下几步:
- 校验库存
- 扣库存
- 创建订单
- 支付
Transactional(rollbackFor = Exception.class)
@Service(value = "DBOrderService")
public class OrderServiceImpl implements OrderService {
@Resource(name = "DBStockService")
private com.crossoverJie.seconds.kill.service.StockService stockService; @Autowired
private StockOrderMapper orderMapper; @Override
public int createWrongOrder(int sid) throws Exception{ //校验库存
Stock stock = checkStock(sid); //扣库存
saleStock(stock); //创建订单
int id = createOrder(stock); return id;
} private Stock checkStock(int sid) {
Stock stock = stockService.getStockById(sid);
if (stock.getSale().equals(stock.getCount())) {
throw new RuntimeException("库存不足");
}
return stock;
} private int saleStock(Stock stock) {
stock.setSale(stock.getSale() + 1);
return stockService.updateStockById(stock);
} private int createOrder(Stock stock) {
StockOrder order = new StockOrder();
order.setSid(stock.getId());
order.setName(stock.getName());
int id = orderMapper.insertSelective(order);
return id;
} }
其实其他的都没怎么改,主要是 Service 层。
@Override
public int createOptimisticOrder(int sid) throws Exception { //校验库存
Stock stock = checkStock(sid); //乐观锁更新库存
saleStockOptimistic(stock); //创建订单
int id = createOrder(stock); return id;
} private void saleStockOptimistic(Stock stock) {
int count = stockService.updateStockByOptimistic(stock);
if (count == 0){
throw new RuntimeException("并发更新库存失败") ;
}
}
对应的 XML:
<update id="updateByOptimistic" parameterType="com.crossoverJie.seconds.kill.pojo.Stock">
update stock
<set>
sale = sale + 1,
version = version + 1,
</set> WHERE id = #{id,jdbcType=INTEGER}
AND version = #{version,jdbcType=INTEGER} </update>
如何保持高并发下数据一致性
对多个更新操作的业务加事物注解。在数据库表中加一个vesion版本控制字段(初始值为0)在更新操作前查询并记录该字段,更新操作完成vesion+1,再次查询vesion与更新操作前记录的值相差1说明前后数据一致,否则回滚更新操作
Java之秒杀活动解决方案的更多相关文章
- 使用Redis中间件解决商品秒杀活动中出现的超卖问题(使用Java多线程模拟高并发环境)
一.引入Jedis依赖 可以新建Spring或Maven工程,在pom文件中引入Jedis依赖: <dependency> <groupId>redis.clients< ...
- Java商城秒杀系统的设计与实战视频教程(SpringBoot版)
课程目标掌握如何基于Spring Boot构建秒杀系统或者高并发业务系统,以及构建系统时采用的前后端技术栈适用人群Spring Boot实战者,微服务或分布式系统架构实战者,秒杀系统和高并发实战者,中 ...
- Atitti.java android反编译解决方案-----虚拟机方案
Atitti.java android反编译解决方案-----虚拟机方案 哈哈,终极解决方案是虚拟机...c++也可以反编译为汇编代码,但无需担心,因为读懂汇编太麻烦..只要不能拿到c++源码就可.. ...
- Java代码安全测试解决方案
Java代码安全测试解决方案: http://gdtesting.com/product.php?id=106
- getActionBar().setTitle(); Java.lang.NullPoint异常解决方案
getActionBar().setTitle(); Java.lang.NullPoint异常解决方案,是由于低版本不支持直接获取的缘故,修改方案: try changing your theme ...
- Call to localhost/127.0.0.1:9000 failed on connection exception:java.net.ConnectException的解决方案
Call to localhost/127.0.0.1:9000 failed on connection exception:java.net.ConnectException的解决方案 作者:凯鲁 ...
- java虚拟机内存不足,“Could not create the Java Virtual Machine”问题解决方案
java虚拟机内存不足,"Could not create the Java Virtual Machine"问题解决方案 在运行java程序时,遇到问题"Could n ...
- 【总结】瞬时高并发(秒杀/活动)Redis方案(转)
转载地址:http://bradyzhu.iteye.com/blog/2270698 1,Redis 丰富的数据结构(Data Structures) 字符串(String) Redis字符串能包含 ...
- 【总结】瞬时高并发(秒杀/活动)Redis方案
1,Redis 丰富的数据结构(Data Structures) 字符串(String) Redis字符串能包含任意类型的数据 一个字符串类型的值最多能存储512M字节的内容 利用INCR命令簇(IN ...
随机推荐
- Nginx+Php-fpm运行原理
一.代理与反向代理 现实生活中的例子 1.正向代理:访问google.com 如上图,因为google被墙,我们需要vpnFQ才能访问google.com. vpn对于“我们”来说,是可以感知到的(我 ...
- Javascript中的null和 undefined
Javascript Undefined vs NULL Many a times we often get confused on whats the difference between UNDE ...
- 【LibreOJ 6280】 数列分块入门 4 (分块)
题目:传送门 听说用define会使代码简洁qwq code: //By Menteur_Hxy #include<cstdio> #include<iostream> #in ...
- 01.Python基础-3.集合容器
1 列表list 1.1 列表介绍 Python内置的一种数据类型是列表:list. 有序的集合,可随时添加和删除其中的元素. 每个元素都分配一个数字 --它的位置,或索引.0,1,2,3-- 可存放 ...
- 《黑白团团队》第八次团队作业:Alpha冲刺 第五天
项目 内容 作业课程地址 任课教师首页链接 作业要求 团队项目 填写团队名称 黑白团团队 填写具体目标 认真负责,完成项目 团队项目Github仓库地址链接. 第五天 日期:2019/6/19 成员 ...
- js sort根据数值大小自动排序(转)
var arrDemo = new Array(); arrDemo[0] = 10; arrDemo[1] = 50; arrDemo[2] = 51; arrDemo[3] = 100; arrD ...
- APS.NET webform中的isPostBack
IsPostBack介绍Page.IsPostBack是一个标志:当前请求是否第一次打开. 调用方法为:Page.IsPostBack或者IsPostBack或者this.IsPostBack或者th ...
- C/C++知识要点5——智能指针原理及自己定义实现
智能指针概述: 智能指针用来管理动态对象.其行为类似于常规指针,重要的差别是:它负责自己主动释放所指向的对象. C++ 11标准库提供两种智能指针:shared_ptr.unique_ptr 差别是: ...
- python3连接Mairadb数据库
<span style="font-size:18px;">#本代码演示的是python3.3.5下连接Mairadb数据库</span> <span ...
- 在外星人电脑上安装windows10和ubuntu16.04双系统小记
最近刚刚入手了一台Alienware Aurora R6,买这货的主要目的是为了研究Deep Learning.之所以没有买组装机的原因,主要是担心组装机的不稳定,而实验经费中的设备费也还相对充足,于 ...