引言

  本文主要描述,服务端做相关秒杀活动的时候,对应的解决方案,即高并发下的数据安全。

优化方案

乐观锁思路

  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之秒杀活动解决方案的更多相关文章

  1. 使用Redis中间件解决商品秒杀活动中出现的超卖问题(使用Java多线程模拟高并发环境)

    一.引入Jedis依赖 可以新建Spring或Maven工程,在pom文件中引入Jedis依赖: <dependency> <groupId>redis.clients< ...

  2. Java商城秒杀系统的设计与实战视频教程(SpringBoot版)

    课程目标掌握如何基于Spring Boot构建秒杀系统或者高并发业务系统,以及构建系统时采用的前后端技术栈适用人群Spring Boot实战者,微服务或分布式系统架构实战者,秒杀系统和高并发实战者,中 ...

  3. Atitti.java android反编译解决方案-----虚拟机方案

    Atitti.java android反编译解决方案-----虚拟机方案 哈哈,终极解决方案是虚拟机...c++也可以反编译为汇编代码,但无需担心,因为读懂汇编太麻烦..只要不能拿到c++源码就可.. ...

  4. Java代码安全测试解决方案

    Java代码安全测试解决方案: http://gdtesting.com/product.php?id=106

  5. getActionBar().setTitle(); Java.lang.NullPoint异常解决方案

    getActionBar().setTitle(); Java.lang.NullPoint异常解决方案,是由于低版本不支持直接获取的缘故,修改方案: try changing your theme ...

  6. 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的解决方案 作者:凯鲁 ...

  7. java虚拟机内存不足,“Could not create the Java Virtual Machine”问题解决方案

    java虚拟机内存不足,"Could not create the Java Virtual Machine"问题解决方案 在运行java程序时,遇到问题"Could n ...

  8. 【总结】瞬时高并发(秒杀/活动)Redis方案(转)

    转载地址:http://bradyzhu.iteye.com/blog/2270698 1,Redis 丰富的数据结构(Data Structures) 字符串(String) Redis字符串能包含 ...

  9. 【总结】瞬时高并发(秒杀/活动)Redis方案

    1,Redis 丰富的数据结构(Data Structures) 字符串(String) Redis字符串能包含任意类型的数据 一个字符串类型的值最多能存储512M字节的内容 利用INCR命令簇(IN ...

随机推荐

  1. TensorFlow+实战Google深度学习框架学习笔记(10)-----神经网络几种优化方法

    神经网络的优化方法: 1.学习率的设置(指数衰减) 2.过拟合问题(Dropout) 3.滑动平均模型(参数更新,使模型在测试数据上更鲁棒) 4.批标准化(解决网络层数加深而产生的问题---如梯度弥散 ...

  2. JavaScript学习笔记(第一天)

    javascript个人笔记 JavaScript的组成 JavaScript是一种运行在客户端的脚本语言 ​ ECMAScript 标准----js的基本的语法 DOM------Document ...

  3. XSS Chanllenges 11-15

    Stage #11 根据提示,发现正则匹配,过滤掉了很多关键字 除on 事件和script 事件外,能执行js 代码的还有a 标签构造的超链接 构造 "><a href=java ...

  4. 3.1、Jinja2模板引擎

    形式最简单的 Jinja2 模板就是一个包含响应文本的文件.示例 3-1 是一个 Jinja2 模板,它和示例 2-1 中 index() 视图函数的响应一样. 示例 3-1 templates/in ...

  5. linux基础正则

    1.^word #匹配word开头的内容,vi/vim编辑器里^代表一行的开头. 2.word$ #匹配以word结尾的内容,vi/vim编辑器里$代表一行的结尾. 3.^$ #表示空行 4.. #代 ...

  6. linux chattr用法

    在linux中,我们有的时候发现linux无法删除一个文件或者目录. huskiesir第一次遇见这个问题还是在一次服务器被不法分子入侵之后的事情,我就发现某个进程很多,根据进程的名字,我搜索关键字找 ...

  7. python第五周:模块、标准库

    模块相关知识: 定义:用来从逻辑上组织python代码(变量.函数.类.逻辑:实现一个功能)本质就是以.py结尾的python文件(文件名:test.py,对应的模块名:test) 附注:包:是用来从 ...

  8. 2019-03-25 SQL SET ANSI_NULLS /SET QUOTED_IDENTIFIER /SET NOCOUNT ON

    use database go /**当 SET ANSI_NULLS 为 ON 时,即使 column_name 中包含空值,使用 WHERE column_name = NULL 的 SELECT ...

  9. java的值传递与引用传递

    一. 经常搞不清楚,当一个对象做为参数传入到方法中时,为啥有时候值能被改变,有时候又不会改变,以下说明原因: 1.当传入的参数,在方法中能被改变的为 引用传递 2.当传入的参数,在方法中没被改变的为 ...

  10. Linux C++服务器端进程SDK

    目标:开发人员在这个SDK的基础上开发,不用关注技术细节,只需要开发对应业务消息处理函数即可 1.每个进程SDK包括一个系统服务和多个业务服务,对外发布服务ID,每个服务有一个请求队列和一个反馈队列, ...