MySQL学习笔记(五)并发时经典常见的死锁原因及解决方法
MySQL都有什么锁?
MySQL有三种锁的级别:页级、表级、行级。
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
算法:
next KeyLocks锁,同时锁住记录(数据),并且锁住记录前面的Gap
Gap锁,不锁记录,仅仅记录前面的Gap
Recordlock锁(锁数据,不锁Gap)
所以其实 Next-KeyLocks=Gap锁+ Recordlock锁
什么情况下会造成死锁?
所谓死锁:
是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去,此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等竺的进程称为死锁进程,表级锁不会产生死锁.所以解决死锁主要还是针对于最常用的InnoDB。
死锁的关键
两个(或以上)的Session加锁的顺序不一致。那么对应的解决死锁问题的关键就是:让不同的session加锁有次序
一些常见的死锁案例
案例一:
需求:将投资的钱拆成几份随机分配给借款人。
起初业务程序思路是这样的:投资人投资后,将金额随机分为几份,然后随机从借款人表里面选几个,然后通过一条条 select for update 去更新借款人表里面的余额等。
抽象出来就是一个session通过for循环会有几条如下的语句:
select * from xxx where id='随机id' for update
基本来说,程序开启后不一会就死锁。这可以是说最经典的死锁情形了。
例如两个用户同时投资,A用户金额随机分为2份,分给借款人1,2。B用户金额随机分为2份,分给借款人2,1。由于加锁的顺序不一样,死锁当然很快就出现了。
对于这个问题的改进很简单,直接把所有分配到的借款人直接一次锁住就行了。
select * from xxx where id in (xx,xx,xx) for update
在in里面的列表值mysql是会自动从小到大排序,加锁也是一条条从小到大加的锁
案例
Session1
以下会话id为主键
mysql> select * from t3 where id in (8,9) for update;
+----+--------+------+---------------------+
| id | course | name | ctime |
+----+--------+------+---------------------+
| 8 | WA | f | 2016-03-02 11:36:30 |
| 9 | JX | f | 2016-03-01 11:36:30 |
+----+--------+------+---------------------+
2 rows in set (0.04 sec)
Session2
select * from t3 where id in (10,8,5) for update;
锁等待中……
其实这个时候id=10这条记录没有被锁住的,但id=5的记录已经被锁住了,锁的等待在id=8的这里。下面测试一番
Session3
mysql> select * from t3 where id=5 for update;
Session4
mysql> select * from t3 where id=10 for update;
+----+--------+------+---------------------+
| id | course | name | ctime |
+----+--------+------+---------------------+
| 10 | JB | g | 2016-03-10 11:45:05 |
+----+--------+------+---------------------+
1 row in set (0.00 sec)
在其它session中id=5是加不了锁的,但是id=10是可以加上锁的。
案例2
在开发中,经常会做这类的判断需求:根据字段值查询(有索引),如果不存在,则插入;否则更新。
更多参考 https://www.cnblogs.com/zejin2008/p/5262751.html
MySQL学习笔记(五)并发时经典常见的死锁原因及解决方法的更多相关文章
- Mysql并发时经典常见的死锁原因及解决方法
1. mysql都有什么锁 MySQL有三种锁的级别:页级.表级.行级. 表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率最高,并发度最低. 行级锁:开销大,加锁慢:会出现死锁 ...
- Java并发编程:Java ConcurrentModificationException异常原因和解决方法
Java ConcurrentModificationException异常原因和解决方法 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.u ...
- MySQL学习笔记五:数据类型
MySQL支持多种数据类型,大致可以分为数值,日期/时间和字符类型. 数值类型 MySQL支持所有标准SQL数值数据类型,包括严格数值数据类型(INTEGER.SMALLINT.DECIMAL和NUM ...
- [转载]常见slave 延迟原因以及解决方法
一 序言在运维线上M-M 架构的MySQL数据库时,接收的比较多关于主备延时的报警: 点击(此处)折叠或打开 check_ins_slave_lag (err_cnt:1)critical-slav ...
- 常见slave 延迟原因以及解决方法
一 序言在运维线上M-M 架构的MySQL数据库时,接收的比较多关于主备延时的报警: 点击(此处)折叠或打开 check_ins_slave_lag (err_cnt:1)critical-slav ...
- 一些常见warning的原因和解决方法
在入职三周后,终于赶齐了接手项目落下两个月的项目,有了一些自己的空闲时间对项目进行整理.主要整理包括类目的整合,从原来一个系统文件夹下几百个文件整改为以MVC设计思想为原则的分文件夹整理类目,井然有序 ...
- MySQL学习笔记(五):MySQL表级锁和行级锁
一:概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...
- mysql学习笔记五 —— MHA
MySQL_MHA ABB(主从复制)-->MHA(实现mysql高可用.读写分离.脚本控制vip飘逸)-->haproxy(对slave集群实现分发,负载均衡)-->keepali ...
- MySql学习笔记(五) —— 存储过程
存储过程是MySql 5支持的特性,它是一组为了完成特定功能的SQL语句集,经过编译之后存储在数据库中,当需要使用该组SQL语句时用户只需要通过指定储存过程的名字并给定参数就可以调用执行它了,简而言之 ...
随机推荐
- 中科曙光I620-G15服务器登录密码破解
服务器型号:中科曙光I620-G15服务器 系统:windowsserver2008R2 单位:保密 服务器登录密码忘记了,进不去桌面,后来在我们云修网工程师的指导下,顺利绕过密码登录系统,然后修改系 ...
- 4.13Python数据处理篇之Matplotlib系列(十三)---轴的设置
目录 目录 前言 (一)设置轴的范围 1.同时对于x,y轴设置 2.分别对与x,y轴的设置 (二)设置刻度的大小 1.普通的刻度设置 2.添加文本的刻度设置 3.主副刻度的设置 (三)设置轴的数据 1 ...
- python import详解
1.import作用 引入模块 2.import的特点 一个程序中,import的模块不会重复被引用,如: # test1.py import test2 print test2.attr # tes ...
- hbase 迁库移库步骤
1 将数据导出 hbase org.apache.hadoop.hbase.mapreduce.Export t_zyzx_grzyfwtjxxb /hbase/data_backup/2018103 ...
- centos7下kubernetes(14。kubernetes-DNS访问service)
我们在部署kubernetes时,会自动部署dns组件,其作用是通过dns解析的方法访问service coredns是一个DNS服务器,每当有新的service被创建,kube-dns会添加该ser ...
- debian8下acme nginx 部署记录
1.更新源 apt update 2.安装curl git apt install curl git -y 3.克隆acme仓库 curl https://get.acme.sh | sh git c ...
- 网络虚拟化基础一:linux名称空间Namespaces
一 介绍 如果把linux操作系统比作一个大房子,那命名空间指的就是这个房子中的一个个房间,住在每个房间里的人都自以为独享了整个房子的资源,但其实大家仅仅只是在共享的基础之上互相隔离,共享指的是共享全 ...
- SpringBoot开发案例之拦截器注入Bean
前言 由于业务需要,需要在拦截器中操作Redis缓存,按照 controller,service层配置发现无法注入,一直报空指针异常. 解决方案 @Configuration public class ...
- spring Jackson 配置笔记
配置代码 // 设置输出时包含属性的风格 this.findAndRegisterModules(); this.setSerializationInclusion(JsonInclude.Inclu ...
- 爬虫基础(三)-----selenium模块应用程序
摆脱穷人思维 <三> : 培养"目标导向"的思维: 好项目永远比钱少,只要目标正确,钱总有办法解决. 一 selenium模块 什么是selenium?seleni ...