悲观锁 vs 乐观锁 vs Redis
企业面对高并发场景采用的方案.
比如 产品抢购高并发时的超发现象.
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>> 杨开振
悲观锁 vs 乐观锁 vs Redis的更多相关文章
- mysql-mysql悲观锁和乐观锁
1.mysql的四种事务隔离级别 I. 对于同时运行多个事务,当这些事务访问数据库中的相同数据时,如果没有采取必要的隔离机制,就会导致各种并发问题. (1)脏读: 对于两个事物 T1, T2, T1 ...
- Hibernate解决高并发问题之:悲观锁 VS 乐观锁
高并发问题是程序设计所必须要解决的问题,解决此类问题最主要的途径就是对对程序进行加锁控制.hibernate对加锁机制同样做出了实现,常用加锁方式为悲观锁和乐观锁.悲观锁指的是对数据被外界(包括本系统 ...
- mysql的锁--行锁,表锁,乐观锁,悲观锁
一 引言--为什么mysql提供了锁 最近看到了mysql有行锁和表锁两个概念,越想越疑惑.为什么mysql要提供锁机制,而且这种机制不是一个摆设,还有很多人在用.在现代数据库里几乎有事务机制,aci ...
- Oracle数据库悲观锁与乐观锁详解
数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫悲观锁呢,悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住.而乐 ...
- 025 hibernate悲观锁、乐观锁
Hibernate谈到悲观锁.乐观锁,就要谈到数据库的并发问题,数据库的隔离级别越高它的并发性就越差 并发性:当前系统进行了序列化后,当前读取数据后,别人查询不了,看不了.称为并发性不好 数据库隔离级 ...
- Mysql锁机制--乐观锁 & 悲观锁
Mysql 系列文章主页 =============== 从 这篇 文章中,我们知道 Mysql 并发事务会引起更新丢失问题,解决办法是锁.所以本文将对锁(乐观锁.悲观锁)进行分析. 第一部分 悲观锁 ...
- Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景
一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--悲观锁( ...
- MySQL学习笔记(四)悲观锁与乐观锁
恼骚 最近在搞并发的问题,订单的异步通知和主动查询会存在并发的问题,用到了Mysql数据库的 for update 锁 在TP5直接通过lock(true),用于数据库的锁机制 Db::name('p ...
- 多线程深入:乐观锁与悲观锁以及乐观锁的一种实现方式-CAS(转)
原文:https://www.cnblogs.com/qjjazry/p/6581568.html 首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每 ...
随机推荐
- Divide and Conquer
1 2 218 The Skyline Problem 最大堆 遍历节点 public List<int[]> getSkyline(int[][] buildings) { ...
- vue使用video.js解决m3u8视频播放格式
今天被这个关于m3u8视频播放不了搞了一下午,这个项目所有的视频流都是m3u8格式的,后台给我们返回的都是m3u8格式的视频流,解决了好长时间,看了好多博客,只有这个博客给我点启发,去解决这个问题,请 ...
- 关于STM32F103+ESP8266+阿里云过程之环境搭建和阿里云数据格式设置及注意点(一)
计划实现功能:将STM32F103采集到的温湿度,PM2.5等数值,通过UART与ESP8266通讯,使得ESP8266对外仅充当串口功能的黑盒.ESP8266通过MTQQ发布订阅数据,设备上传.接收 ...
- DesignPattern系列__10单例模式
单例模式介绍 单例模式,是为了确保在整个软件体统中,某个类对象只有一个实例,并且该类通常会提供一个对外获取该实例的public方法(静态方法). 比如日志.数据库连接池等对象,通常需要且只需要一个实例 ...
- 【算法】【排序】【交换类】快速排序QuickSort
#include<stdio.h> //快速排序 int main(){ ,,,,,,,,}; +; //基准指针 ; //慢指针 int* j=a; //快指针 int QS(int* ...
- 微信JSSDK签名
微信JS-SDK说明文档 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 生成签名 1.签名规则 参与签名的 ...
- Vue小事例
login <!DOCTYPE html><html lang="ZH-cn"> <head> <meta charset="U ...
- 多态、继承、this、super
先放一下多态的定义: (360词典上的哈) 多态(Polymorphism)按字面的意思就是"多种状态".在面向对象语言中,接口的多种不同的实现方式即为多态.引用Charlie C ...
- 关于JSP页面的静态包含和动态包含
JSP中有两种包含:静态包含:<%@include file="被包含页面"%> 和 动态包含:<jsp:include page="被包含页面&quo ...
- 大数据学习之旅2——从零开始搭hadoop完全分布式集群
前言 本文从零开始搭hadoop完全分布式集群,大概花费了一天的时间边搭边写博客,一步一步完成完成集群配置,所以相信大家按照本文一步一步来完全可以搭建成功.需要注意的是本文限于篇幅和时间的限制,也是为 ...