数据库原理
数据库原理之 锁机制
你是否在经常写业务代码,会写许多SQL 语句,但是对 数据库的原理,怎么运作,缺一点都不知道呢?
今天主要是学习了三个知识点。
- 隔离级别 与 并发一致性问题
- InnoDB 存储引擎 行锁
- MyISAM 存储引擎 表锁
一 隔离级别
首先讲述下 ,什么是 并发一致性问题?
在 数据库中,数据需要满足 四个原则 ACID 原则。这块是 基础知识,不是机械的死记硬背就行,需要结合实例来进行理解。
为什么会出现 一致性问题?
- 当有多个事务的时候,每个事务都会操作数据库,这个时候可能就会出现 并发 一致性问题。
讲述了这么多,你可能会问,到底什么TM的叫 并发一致性问题?能不能具体点,说点 阳间的事情。
简单来说,并发一致性问题分为四类。
- 丢失更新
- 脏读
- 不可重复读
- 幻读
一般来说,要理解这四个问题,需要 结合 ” 银行转账 “ 的实例帮助理解。但是,今天我就不,我要给你画个图,让你更容易读懂这些个概念。
1 丢失更新
2 脏读
3 不可重复读
4 幻读
大概描述下,不太想画图了,就是 当前事务 要读 某个范围的值,读完成后,另外一个事务,执行了插入操作。导致最后,出现了一种 数据不一致问题。
解决方法
解决并发控制的方法是*,但是*比较复杂,所以MYSQL 提供了事务的隔离级别 来 解决上述问题的三种方法:
- 可提交读。
- 可重复读。
- 可串行化。
三种解决 方案,MySQL 默认的 隔离级别是 可重复读。
二 InnoDB 存储引擎
什么是 InnoDB 存储引擎?
一听到这个名词 就有点蒙圈,都不知道这是什么,但是呢,这个引擎确实我们平时使用最多的引擎,因为每当创建一个 数据表 时,都会创建一个默认 的 InnoDB 引擎的数据表。
MVCC (多版本并发控制) 是 InnoDB 实现 隔离级别的一种具体方式,可以实现 提交读 和 重复读 两种隔离级别。
1 行锁
InnoDB 默认的锁 是行锁,行锁,就是锁 记录行的,与表锁 对立开来。
2 具体操作
事务一:
# 事务一
# 关闭自动提交
SET autocommit=0;
# 查询 表 全部数据
SELECT * FROM inno_lock;
#查询
SELECT * FROM inno_lock WHERE id='3';
# 更新 数据,会对这一行数据 加 read 锁
UPDATE inno_lock SET NAME='30' WHERE id =3;
COMMIT;
事务二:
USE test;
SET autocommit=0;
SELECT * FROM inno_lock WHERE id='3';
SELECT * FROM inno_lock
# 当 T1 给 行上了 read 锁,之后,执行这一句,就会出现 线程阻塞状态。
UPDATE inno_lock SET NAME='60' WHERE id =6;
COMMIT;
首先,要把 自动提交关闭,才能模仿两个事务的并发控制。
- 当 T1 进行 写操作(新增,修改,删除)时,会对某一行进行上锁。那么,与此同时 ,T2 并不能 对 这一行记录 进行 写操作,但是可以进行 读操作,读操作 却与 T1 结束时的 结果不同。
- 如果 T2 要对 这一行记录进行 修改,则会出现 阻塞,等待 T1 执行完毕。
3 行锁升级成表锁
- 当 没有索引或者 索引失效时 行锁会升级成表锁。
4 Next-key 锁 (间隙锁)
间隙锁是为了解决 GAP 问题,也就是 幻读问题。
这个锁 会对 范围内 的 每个值上一个锁。
5 MVCC 原理
TRX_ID: 事务ID,版本
多版本管理,基于 undo 日志。
每一行有三个隐藏的列,分别是 版本号,row_id, undo地址列。
三 MyISAM 存储引擎
1 表锁
MyISam 默认的锁 是 表锁。
锁的分类,按照粒度分类分为 表锁与行锁。
按照操作,分为 写锁与读锁。也就是 共享锁与排它锁
有两个事务,当 T1把 TableA上了读锁,那么 在T1 中,只有TableA 是可见的,也就是说只能读取TableA表,其他表并不能查询。另外一个事务T2中,所有表都能读,但是如果要对TableA表进行 更新操作,将会出现 等待状态(阻塞状态)。
使用 读锁
事务一 | 事务二 |
---|---|
使用 读锁锁定 表后,只用 当前被锁表可见,本事务中的任何表都是不可见的。 | 该事务中,所有表都是可以读的,但是 TableA 表不能 进行写操作。其他表都可以写。 |
使用写锁
事务一 | 事务二 |
---|---|
使用 写锁锁定 表 之后,其他表 不可见,被锁的表能进行 读和写操作 | 其他表能写,也能读,被锁表不能使用。 |
上一篇: sql开窗函数初体验
下一篇: 类的成员方法 小练习