高并发秒杀系统解密—后端 java 程序员力荐

那些场景属于秒杀业务?

  1. 商品抢购

  2. 群红包

  3. 优惠卷领取

  4. 抢火车票

  5. 在线预约

小蝌蚪跑步比赛 起点线的故事

=============================================================================

关于锁的那些事

==========================================================================

悲观锁解析

========================================================================

对于悲观锁的概念解释主要有两种,但本质上悲观锁主要用于数据库访问的并发控制上。

  • 解释一

悲观锁是指对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态,在悲观锁的情况下,为了保证事务的隔离性,就需要一致性锁定读。读取数据时给加锁,其它事务无法修改这些数据。修改删除数据时也要加锁,其它事务无法读取这些数据。

  • 解释二

在关系数据库管理系统里,悲观并发控制(又名“悲观锁”,Pessimistic Concurrency Control,缩写“PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作都某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。

悲观锁处理流程

  1. 在对任意记录进行修改前,先尝试为该记录加上排他锁(exclusive locking)

  2. 如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常

  3. 如果成功加锁,那么就可以对记录做修改,事务完成后就会解锁了

  4. 其间如果有其他对该记录做修改或加排他锁的操作,都会等待我们解锁或直接抛出异常

悲观锁优点

  • 悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。

  • 悲观锁基于 DB 层面实现,对业务代码无入侵,使用方便

悲观锁缺点

  • 悲观锁适用于可靠的持续性连接,诸如 C/S 应用。 对于 Web 应用的 HTTP 连接,先天不适用

  • 锁的使用意味着性能的损耗,在高并发、锁定持续时间长的情况下,尤其严重。 Web 应用的性能瓶颈多在数据库处,使用悲观锁,进一步收紧了瓶颈

  • 非正常中止情况下的解锁机制,设计和实现起来很麻烦,成本还很高

  • 不够严谨的设计下,可能产生莫名其妙的,不易被发现的死锁问题

  • 悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发访问性不好

乐观锁解析

====================================================================

在关系数据库管理系统里,乐观并发控制(又名“乐观锁”,Optimistic Concurrency Control,缩写“OCC”)是一种并发控制的方法。它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。乐观事务控制最早是由孔祥重(H.T.Kung)教授提出。

相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本

优点与不足

乐观并发控制相信事务之间的数据竞争(data race)的概率是比较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁。但如果直接简单这么做,还是有可能会遇到不可预期的结果,例如两个事务都读取了数据库的某一行,经过修改以后写回数据库,这时就遇到了问题。

乐观锁实现流程

保证三步操作原子性

小伙伴们有兴趣想了解内容和更多相关学习资料的请点赞收藏+评论转发+关注我,后面会有很多干货。如果在阅读过程中有疑问,请留言讨论

原文出处:大战618,决胜双十一 高并发秒杀系统解密—后端java程序员力荐_Java_InfoQ写作社区 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
导入依赖Mybatis Plus 依赖,在Mybatis Plus官网安装模块,选择spring boot的maven依赖包 <!-- Mybatis Plus组件--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.0</version> </dependency> 2.配置文件 spring: #thymeleaf配置 thymeleaf: # 关闭缓存 cache: false datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/seckill?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai username: root password: 123456 hikari: # 连接池名(据说是最快的连接池) pool-name: DataHikariCP # 最小空闲连接数 minimum-idle: 5 # 空闲连接存活最大时间,默认600000(10分钟) idle-timeout: 18000 # 最大连接数,默认10 maximum-pool-size: 10 # 从连接池返回的连接自动提交 auto-commit: true # 连接最大存活时间,0表示永久存活,默认1800000(30分钟) max-lifetime: 1800000 # 连接超时时间,默认30000(30秒) connection-timeout: 30000 # 测试连接是否可用的查询语句 connection-test-query: SELECT 1 #Mybatis-plus配置 mybatis-plus: #配置Mapper.xml映射文件 mapper-locations: classpath*:/mapper/*Mapper.xml #配置Mybatis数据返回数据别名(默认别名是类名) type-aliases-package: com.csl.seckill.pojo logging: level: com.csl.seckill.mapper: debug 3.创建包 在java包下面的seckill包下,创建controller,service,pojo,mapper包,在service包下创建impl包 在resource包下创建mapper包,放置mapper文件 其中templates包下放置前端页面 4.测试 ①在启动类中添加注解:@MapperScan("com.csl.seckill.pojo"),添加此注解以后,com.csl.seckill.pojo包下面的接口类,在编译之后都会生成相应的实现类。 ②写一个页面跳转controller 首先声明是controller层(@controller) 请求地址时http://localhost:8080/demo/hello 使用@RequestMapping注解进行映射,返回映射的页面名称 @Controller @RequestMapping("/demo") public class DemoController { /** * 测试页面跳转 * @param model * @return */ @RequestMapping("/hello") public String hello(Model model){ model.addAttribute("name","csl"); return "hello"; } } ③创建一个hello页面: <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="U
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值