悲观锁 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 首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每 ...
随机推荐
- 确保Web安全的HTTPS
HTTP在安全方面主要有以下不足: 1. 通信使用明文不加密,内容可能会被窃听:(TCP/IP就是可能被窃听的网络) 2. 不验证通信方的身份,因此有可能遭遇伪装: (无法判断请求或响应是否正确,是否 ...
- RobotFramework_1.简介和安装
RobotFramework_1.简介与安装 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bot ...
- 搭建nexus私服
一.安装 1.从网上下载nexus软件https://www.sonatype.com/download-oss-sonatype 下载Nexus Repository Manager OSS软件包 ...
- Docker——理解好镜像和容器的关系
关注公众号,大家可以在公众号后台回复“博客园”,免费获得作者 Java 知识体系/面试必看资料. 镜像也是 docker 的核心组件之一,镜像时容器运行的基础,容器是镜像运行后的形态.前面我们介绍了 ...
- 解决:Navicat连接不上MySQL 8.0
转载自 https://www.cnblogs.com/shiysin/p/shiysin.html Navicat连接不上,总是报错1251: 原因是MySQL8.0版本的加密方式和MySQL5.0 ...
- java并发编程(四)----(JUC)Lock锁初探
首先我们来回忆一下上一节讲过的synchronized关键字,该关键字用于给代码段或方法加锁,使得某一时刻它修饰的方法或代码段只能被一个线程访问.那么试想,当我们遇到这样的情况:当synchroniz ...
- axios配置请求头content-type
现在前端开发中需要通过Ajax发送请求获取后端数据是很普遍的一件事情了,鉴于我平时在撸码中用的是vue技术栈,今天这里来谈谈我们常用的发Ajax请求的一个插件—axios.> 现在网上可能发送A ...
- 基于 Lerna 管理 packages 的 Monorepo 项目最佳实践
本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/NlOn7er0ixY1HO40dq5Gag作者:孔垂亮 目录 一.背景二.Monorepo vs M ...
- 记一次JPA遇到的奇葩错误——本地sql不识别表名的别名
记一次JPA遇到的奇葩错误——本地sql不识别表名的别名 报错:Unknown column 'our' in 'field list' 起因:需要本地sql查询后,分页返回自定义对象.报错信息如下: ...
- 程序员的专属微信公众号编辑器:定制 Markdown 转 HTML
效果(Gif) 点击我查看 仓库地址 https://github.com/cdk8s/cdk8s-markdown-to-html https://gitee.com/cdk8s/cdk8s-mar ...