企业面对高并发场景采用的方案.

比如 产品抢购高并发时的超发现象.

1 悲观锁
悲观锁 需要数据库本身提供支持(Oracle和MySQL都是支持的).
实现细节:
当前 数据库事务 读取到产品后, 就将目标数据直接锁定(select ... for update), 不允许别的线程进行读写操作, 知道 当前数据库事务完成自动释放锁.
悲观锁中, 资源只能被一个事务锁持有, 所以也被称为 独占锁 or 排它锁.

悲观锁的优点是实现简单好理解, 缺点是过多的等待和响应的事务切换导致性能问题.
为提高运行效率, 可以采用 乐观锁.

2 乐观锁
乐观锁 是一种 不使用数据库锁 和 不阻塞线程并发 的方案.
著名的 CAS(Compare and Swap): 线程在修改目标数据时, 会将目标数据的当前状态和旧状态进行比较(Compare), 如果状态一直, 就可以认为 数据木有被修改过, 否则就认为数据已经不同步了, 当前计算作废, 不做任何修改操作(回滚).
CAS方案却会引发 ABA问题, 就是共享值回退导致数据的不一致问题, 有点像脏读.
采用 带版本号(version)的乐观锁方案, 再配合CAS, 就可以解决 ABA问题了.
实现细节:
给产品表添加 version字段, 只要操作过程中有修改产品状态(比如减少库存), 无论是业务正常 回退 还是异常, 版本号只增不减. 即
update t_product set stock=stock-#{quantity}, version=version+1
where id=#{id} and version=#{version}
乐观锁没有独占资源和阻塞任何线程, 所以乐观锁也称为 非独占锁 or 无阻塞锁.
在实际使用乐观锁时, 会发现线程的业务失败率会很高, 针对这点可以对 乐观锁 引入重入机制. 也就是一旦业务失败, 不是立即结束请求, 而是重新做一次乐观锁流程, 可限制重入时间or重入次数.

乐观锁优点是不独占不阻塞, 缺点是实现相对复杂.

3 Redis
有些企业已经开始使用 NoSQL 来处理高并发问题, 代表就是 Redis(内存数据库).
首先, Redis 是内存数据库, 所以性能是没的说的. 其次, Redis Lua 在 Redis 的执行中是具备原子性的, 所以不会发送超发现象.
两步设计:
1) 使用 Redis 响应高并发用户请求
即用 Redis 代替原来的磁盘数据库 读写, 保证性能和数据一致性.
2) 定时持久化 Redis 数据
内存数据存储是不稳定的, 我们需要及时将保存在内存中的数据持久化到磁盘数据库中.

使用 Redis 效率要比悲观锁和乐观锁机制快上数倍, 但是千万记住 Redis 的存储基于内存, 如果操作不当容易引发数据的丢失, 所以使用 Redis 时建议使用独立的 Redis 服务器, 而且要做好备份和容灾等手段.

参考:
https://www.cnblogs.com/zhiqian-ali/p/6200874.html
<<深入浅出 Spring Boot 2.x>> 杨开振

最新文章

  1. 一步步学习javascript基础篇(2):作用域和作用域链
  2. 《UML大战需求分析》阅读笔记03
  3. Android 的上下文菜单: Context Menu,registerForContextMenu(getListView())
  4. int转多进制
  5. Mybatis批量插入oracle,mysql
  6. 使用idea Live Template实现eclipse syso自动提示代码功能
  7. java虚拟机--jvm client模式与server模式的区别
  8. swift 取消UIButton选中高亮状态
  9. 2013年五大主流浏览器 HTML5 和 CSS3 兼容性大比拼
  10. 推荐一个非常牛逼的并发httpful的库(php)
  11. Dapper/SqlMapper映射对应问题
  12. Session Cookies随笔
  13. 搭建使用create-react-native-app 搭建app开发环境
  14. ubuntu14安装TensorFlow
  15. ADT和DS
  16. 每年有20万人进军IT行业,为何还会人才短缺?
  17. 基于S3C2440的嵌入式Linux驱动——看门狗(watchdog)驱动解读
  18. angular组件层次与军事指挥层级职责的联系
  19. Loadrunner参数化如何在记事本中将参数值显示超过100个参数值
  20. Ubantu 更新时间方法

热门文章

  1. 深入学习 Intellij IDEA 调试技巧
  2. 【Java】Class JavaLaunchHelper is implemented in both ** and **
  3. 【Java】设置 JPanel 宽度
  4. 【Java】判断字符串是否含字母
  5. Android开发——通过wifi接收IPCamera视频流
  6. spring学习笔记之---bean管理
  7. 详解 git 忽略文件 删除远端仓库的文件
  8. 一个项目的SpringCloud微服务改造过程
  9. 最小化docker镜像
  10. AWS Aurora数据库 Multi-Master 小测