mysql锁机制与结构

一、锁的基础与行锁的特点

1. 概念

1. 在开发多用户、数据库驱动的应用时,相当大的一个难点就是解决并发性的问题,目前比较常用的解决方案就是锁机制。

2. 锁机制也是数据库系统区别于文件系统的一个关键特性。

3. InnoDB 存储引擎和 MyISAM 存储引擎使用的是完全不同的策略,我们必须分开来讲。

2. 锁特性

一旦事务锁住一页或者一行或者一张表的数据,被锁住就不能被操作了(写操作)

3. 锁类型

3.1 表级锁

表级锁:锁住一张表的数据
		存储引擎:myisam
		开销小,加锁的难度小,速度快,不会出现死锁的请情况,但是会发生锁冲突,并发最高

3.2 页级锁

页级锁:锁住某一页数据,大约16kb
		存储引擎:BDB(支持事务,已经不用了)
		开销中等,枷锁难度中等,速度中等,锁冲突中等

3.3 行级锁

行级锁:锁住某一行的数据
		存储引擎:innodb
		开销大,枷锁速度慢(检索量大),难度高,锁冲突最低,并发最低
3.3.1 行级锁类型
排它锁

排它锁

select * from user where id =1 fro update
	特性:
		对于普通的select查询不会有限制
		排它锁不能与其他锁(排它锁,共享锁)一起使用(否则锁等待),不能读,不能写
		因为mysql的事务会默认给你 update、insert、alter、delete,这样一些写的操作默认加上一把排它锁
		使我们的业务强制进入串行化
			  
	应用场景:
		支付
		订单状态  
		秒杀(超卖)
共享锁

共享锁

select * from user where id =1 lock in share mode
	特性:
		能读不能写
		可以和共享锁一起使用,不能与排它锁一起使用(否则锁等待)

	使用场景:
		mvcc

4. 总结

  1. 一旦事务锁住一页或者一行或者一张表的数据,被锁住就不能被操作了(写操作)

  2. 开启事务以后,写操作(alter、delete、insert、update)的sql语句,只要没提交就把不会生效。

  3. 当前查询:一般指的是加锁的select查询

  4. 快照查询:一般指的是没加锁的普通查询

  5. 普通查询不会受到加锁的影响,依然能够获取加锁后的数据

  6. 排它锁不能与其他锁(排它锁,共享锁)一起使用(否则锁等待),不能读,不能写

  7. 共享锁可以和共享锁一起使用不能与排它锁一起使用(否则锁等待)

二、死锁的产生于处理

1. 死锁简介

属于一个现象

死锁的错误显示

  1. ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

在这里插入图片描述

  1. 还有一种可能不会直接报错,而是事务1在等待事务2 ,事务2在等待事务1

2. 死锁产生的原因

产生原因

	因为两个以上的进程来争夺资源(查询数据),造成互相等待的现象(锁等待)。
			事务1等待事务2提交或者回滚,事务2等待事务1提交或者回滚
	最容易产生死锁:
			模糊查询、范围查询

3. 解决办法

解决办法

		1. 锁等待的时间 wait_timeout=120 --设置的是锁等待的时间
				锁等待时间结束之后会有一个失败和一个成功mysql的选择与事务的大小有关 select 舍小保大

		2. mysql自己去检测到
		
		3. 不能彻底的解决,只能是尽量的避免

4. 避免死锁

避免死锁

	1. 以固定的顺序去访问表 或者 行

	2. 业务允许的情况下把大的事务拆分成小的事务

三、乐观锁与悲观锁

1. 乐观锁

乐观锁(Optimistic Lock)

	顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,
	但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。
	乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。

1.1 MVCC-乐观锁的解释

MVCC: 多版本并发控制 (Multiversion concurrency control, MCC 或 MVCC),是数据库管理系统常用的一种并发控制,也用于程序设计语言实现事务内存。

主键   用户名    年龄    数据的版本号  数据第一次新增 version默认 1
id    username   age    version 
1      name       1      1

select * from user where id =1;
update user set username = '111',version = version+1 where id =1;

2. 悲观锁

悲观锁(Pessimistic Lock)

	顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,
	这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,
	比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

四、间隙锁与行锁升级表锁

1. 间隙锁

1.1 概念

当我们使用范围查询而不是等式查询,并请求(写操作)或者加上排它锁的时候
间隙锁还是属于行级锁

1.2 危害

如果在查询中通过范围去查询摸,锁住的范围会是所有索引的键值,即使这个数据不存在

2. 行锁升级表锁

2.1 为什么行锁会升级表锁的原因

行锁升级为表锁(innodb

	行级锁加锁的where条件,在不加索引的字段(除主键、唯一索引(字段)之外)上进行加锁,会升级为表锁
	
	加了索引之后,加锁会根据普通索引的基础上来进行加锁,而一旦索引失效(范围查询、模糊查询)还是会升级为表锁

2.2 如何避免

不只是排它锁,共享锁也是一样的
	1. 尽可能是索引字段进行加锁
	2. 尽可能使用等式而不是范围查询、模糊查询
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值