Mysql中的锁

1. Mysql引擎

MySQL引擎就是指表的类型。数据库的存储引擎决定了表在计算机中的存储方式。
分类:通过show engines;查看。结果如下图所示、

mysql引擎分类

创建新表时如果不指定存储引擎,那么系统就会使用默认的存储引擎,MySQL5.5之前的默认存储引擎是MyISAM,5.5之后就改为了InnoDB。
查看数据库的引擎命令:
对比:
在这里插入图片描述

show variables like '%storage_engine%' 

2. 锁的定义

概念:锁是计算机协调多个进程或线程并发访问某一资源的机制。锁可以保证数据并发访问的一致性有效性;锁是Mysql在服务器层存储引擎层的的并发控制。
注意:加锁是消耗资源的,锁的各种操作,包括获得锁、检测锁是否是否已解除、释放锁等.

3. 锁的分类

(1)按锁的粒度分类

根据锁的粒度划分,可以将锁分为行级锁页级锁表级锁

行级锁:是MySQL锁定粒度最小的一种锁,表示只针对当前操作的进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,单加锁开销最大。InnoDb支持行级锁。
页级锁:是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。
表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。

对比:表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB支持页级锁

(2)按锁的级别分类

根据锁的级别划分,可以将锁分为共享锁排它锁

在这里插入图片描述
共享锁:又称"读锁",是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。

SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE;  --加共享锁 

排它锁:又称"写锁",如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

SELECT * FROM table_name WHERE ... FOR UPDATE;--加排它锁 

(3)按加锁的方式分类

按加锁的方式,可以分为自动锁显示锁
Tips: INSERT、UPDATE、DELETE InnoDB会自动加排他锁,对于普通SELECT语句,InnoDB不会加任何锁

(4)按操作进行分类

按操作进行分类,可分为DML锁,DDL锁

DML(data manipulation language):数据操作语言。
它们是SELECT、UPDATE、INSERT、DELETE,这4条命令是用来对数据库里的数据进行操作的语言,这些语句的操作对于的锁为DML锁

DDL(data definition language):数据定义语言
DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表的结构,数据类型,表之间的连接和约束等初始化工作上,他们大多在建立表时使用。这些语句的操作对于的锁为DDL锁

(5) 按适用方式分类

按适用方式分类:悲观锁和乐观锁

悲观锁(Pessimistic Concurrency Control,PCC):假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。

乐观锁(Optimistic Concurrency Control,OCC):假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。

优缺点:
① 悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发性不好。但这也保证了数据的安全性
② 乐观锁不能解决脏读,加锁的时间要比悲观锁短(乐观锁可以获得较好的并发访问性能。但是不能保证安全性。比如:如果第二个用户恰好在第一个用户提交更改之前读取了该对象,那么当他完成了自己的更改进行提交时,数据库就会发现该对象已经变化了,这样,第二个用户不得不重新读取该对象并作出更改。

4. 死锁的原理及分析

(1) MVCC

​MySQL InnoDB存储引擎,实现的是基于多版本并发控制协议—MVCC(Multi-Version Concurrency Control) 。
MVCC最大的好处,读不加锁,读写不冲突。在读多写少的应用中,读写不冲突是非常重要的,极大的增加了系统的并发性能,这也是为什么现阶段,几乎所有的RDBMS,都支持了MVCC。

(2)两段锁:2PL

​ 传统RDBMS加锁的一个原则,就是2PL (二阶段锁):Two-Phase Locking。锁操作分为两个阶段:加锁阶段与解锁阶段,并且保证加锁阶段与解锁阶段不相交。
过程:
在这里插入图片描述

(3)为什么会发生死锁

MyISAM中是不会产生死锁的,因为MyISAM总是一次性获得所需的全部锁,要么全部满足,要么全部等待。而在InnoDB中,锁是逐步获得的,就造成了死锁的可能。
在InnoDB中,行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,MySQL就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。
当两个事务同时执行,一个锁住了主键索引,在等待其他相关索引。另一个锁定了非主键索引,在等待主键索引。这样就会发生死锁。

(4)如何避免死锁

(1)如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。
(2)在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
(3)对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL(Locking)用于控制并发访问数据库资源以避免数据一致性问题。MySQL支持多种类型的,这些可以分为以下几类: 1. **共享(Shared Locks, S)**: - 允许读取数据,但阻止其他事务对同一行进行写操作。如果多用户同时请求共享,则所有请求都会立即获得。 ```sql SELECT * FROM table WHERE id = 1; -- 获取S ``` 2. **排他(Exclusive Locks, X)**: - 只允许一个事务独占一行,阻止其他事务进行读取或写入操作。 ```sql INSERT INTO table VALUES (1, 'value'); -- 获取X UPDATE table SET column = 'new_value' WHERE id = 1; -- 获取X DELETE FROM table WHERE id = 1; -- 获取X ``` 3. **意向(InnoDB Only, IX)**: - InnoDB存储引擎特有的,用于定表级,允许事务定整个表以便在其范围内进行插入或删除操作。 ```sql LOCK TABLES table WRITE; -- 获取IX ``` 4. **行级乐观(Row-Level Optimistic Locking, ROWX)**: - MySQL的默认行为是行级定,但可以通过`SELECT ... FOR UPDATE`语句实现乐观,它会检查行的版本号是否与先前读取时一致。 5. **死(Deadlocks)**: - 当两个或更多的事务因等待对方释放资源而互相阻塞时,就会发生死。 6. **自旋(Spin Locks)**: - 这不是MySQL的标准机制,而是某些库或优化策略使用的高级概念,它让进程在获取失败时循环尝试,直到成功。 了解这些的类型有助于管理和优化并发性能,尤其是在高并发环境下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值