当前位置:   article > 正文

MySQL高级篇——锁的概述与案例应用_mysql锁举案例

mysql锁举案例

文章目录:

1.锁的概述

2.MySQL并发事务访问相同记录

2.1 读-读情况

2.2 写-写情况

2.3 读-写或写-读情况

2.4 并发问题的解决方案

3.锁的不同角度分类

3.1 从数据操作的类型划分:读锁、写锁

3.2 从数据操作的粒度划分:表级锁、页级锁、行锁

3.2.1 表锁——读锁、写锁

3.2.2 表锁——意向锁

3.2.3 行锁——记录锁

3.2.4 行锁——间隙锁

3.2.5 行锁——临键锁

3.2.6 行锁——插入意向锁

3.2.7 页锁

3.3 从对待锁的态度划分:乐观锁、悲观锁

3.3.1 悲观锁

3.3.2 乐观锁

3.3.3 对比

3.4 全局锁

3.5 死锁


1.锁的概述

在数据库中,除传统的计算资源(如 CPU RAM I/O 等)的争用以外,数据也是一种供许多用户共享的资源。为保证数据的一致性,需要对 并发操作进行控制 ,因此产生了 。同时 锁机制 也为实现 MySQL的各个隔离级别提供了保证。 锁冲突 也是影响数据库 并发访问性能 的一个重要因素。所以锁对数据库而言显得尤其重要,也更加复杂。

2.MySQL并发事务访问相同记录

2.1 -读情况

- 情况,即并发事务相继 读取相同的记录 。读取操作本身不会对记录有任何影响,并不会引起什么问题,所以允许这种情况的发生。

2.2 -写情况

- 情况,即并发事务相继对相同的记录做出改动。 在这种情况下会发生 脏写 的问题,任何一种隔离级别都不允许这种问题的发生。所以在多个未提交事务相继对一条记录做改动时,需要让它们 排队执行 ,这个排队的过程其实是通过 来实现的。这个所谓的锁其实是一个 内存中的结构 ,在事务执行前本来是没有锁的,也就是说一开始是没有 锁结构 和记录进行关联的。
当一个事务想对这条记录做改动时,首先会看看内存中有没有与这条记录关联的 锁结构 ,当没有的时候就会在内存中生成一个 锁结构 与之关联。比如,事务 T1 要对这条记录做改动,就需要生成一个 锁结构 与之关联:

小结几种说法:
不加锁 :意思就是不需要在内存中生成对应的 锁结构 ,可以直接执行操作。
获取锁成功,或者加锁成功:意思就是在内存中生成了对应的 锁结构 ,而且锁结构的 is_waiting 属性为 false ,也就是事务可以继续执行操作。
获取锁失败,或者加锁失败,或者没有获取到锁: 意思就是在内存中生成了对应的 锁结构 ,不过锁结构的 is_waiting 属性为 true ,也就是事务 需要等待,不可以继续执行操作。

2.3 -写或写-读情况

- - ,即一个事务进行读取操作,另一个进行改动操作。这种情况下可能发生 脏读 不可重复读 幻读 的问题。
各个数据库厂商对 SQL 标准 的支持都可能不一样。比如 MySQL REPEATABLE READ 隔离级别上就已经解决了 幻读 问题。

2.4 并发问题的解决方案

怎么解决 脏读 不可重复读 幻读 这些问题呢?其实有两种可选的解决方案:
方案一:读操作利用多版本并发控制( MVCC ,下章讲解),写操作进行 加锁
        普通的SELECT 语句在 READ COMMITTED REPEATABLE READ 隔离级别下会使用到 MVCC 读取记录。
        在 READ COMMITTED 隔离级别下,一个事务在执行过程中每次执行 SELECT 操作时都会生成一个ReadView ReadView 的存在本身就保证了 事务不可以读取到未提交的事务所做的更改 ,也就是避免了脏读现象;
        在 REPEATABLE READ 隔离级别下,一个事务在执行过程中只有 第一次执行 SELECT 操作 才会生成一个ReadView ,之后的 SELECT 操作都 复用 这个 ReadView ,这样也就避免了不可重复读和幻读的问题。
方案二:读、写操作都采用 加锁 的方式。
小结对比发现:
        采用 MVCC 方式的话, - 操作彼此并不冲突, 性能更高
        采用 加锁 方式的话, - 操作彼此需要 排队执行 ,影响性能。
一般情况下我们当然愿意采用 MVCC 来解决 - 操作并发执行的问题,但是业务在某些特殊情况下,要求必须采用 加锁 的方式执行。下面就讲解下 MySQL 中不同类别的锁。

3.锁的不同角度分类

3.1 从数据操作的类型划分:读锁、写锁

读锁 :也称为 共享锁 、英文用 S 表示。针对同一份数据,多个事务的读操作可以同时进行而不会互相影响,相互不阻塞的。
写锁 :也称为 排他锁 、英文用 X 表示。当前写操作没有完成前,它会阻断其他写锁和读锁。这样就能确保在给定的时间里,只有一个事务能执行写入,并防止其他用户读取正在写入的同一资源。
需要注意的是对于 InnoDB 引擎来说,读锁和写锁可以加在表上,也可以加在行上。

下面进行简单的案例测试:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/685463
推荐阅读
相关标签