事务的定义:满足 ACID 特性的一组操作。(ACID:酸)
在关系数据库中,一个事务可以是一条 SQL 语句、一组 SQL 语句或整个程序。使用 Commit 提交一个事务,使用 Rollback 进行回滚。
事务是不可分割的最小单位,事务的所有操作要么全部提交成功,要么全部失回滚。
在事务执行前后,所有事务对同一个数据的读取结果都是相同的。
一个事务所做的修改在最终提交以前,对其它事务是不可见的。
一个事务被提交,所做的修改会永远保存到数据库中。即使系统崩溃,事务执行的结果也不会丢失。
在并发环境下,事务的隔离性很难保证,因此会出现很多事务并发的问题。
定义:一个事务的更新操作被另外一个事务的更新操作所替换。
例如:T1 和 T2 两个事务都对一个数据进行修改,T1 先修改并提交生效,T2 随后修改,T2 的修改覆盖了 T1 的修改。
定义:一个事务读到另一个事务未提交的数据。
例如:T1 修改一个数据但未提交,T2 随后读取这个数据。如果 T1 撤销了这次修改,那么 T2 读取的数据是脏数据。
定义:一个事务连续读取两次的数据不一致。因为在第一次读取后,另一个事务对数据进行了修改。
例如:T2 读取一个数据,T1 对该数据做了修改。如果 T2 再次读取这个数据,此时读取的结果和第一次读取的结果不同。
定义:幻读是不可重复读的一种情况。第一次读取时,数据不存在;第二次读取,数据出现了。
产生并发不一致问题的主要原因是破坏了事务的隔离性,解决方法是通过并发控制来保证隔离性。并发控制可以通过封锁来实现,但是封锁操作需要用户自己控制,相当复杂。数据库管理系统提供了事务的隔离级别,让用户以一种更轻松的方式处理并发一致性问题。
封锁的大小称为封锁粒度。封锁粒度越小,系统的并发程度就越高,系统开销也越大。
对表上的某一行或多行加锁。
对整张表加锁。
Record Lock,属于行锁的一种,对索引项加锁。其他事务不能修改加锁项。
Gap Lock,对索引项之间的间隙加锁,但不包含索引项本身。其他事务不能在加锁范围内插入数据,防止幻读。
对索引项和索引项之间的间隙加锁。是记录锁和间隙锁的结合。可解决幻读问题。
作用:读写锁是行级锁。
原理:分为互斥锁和共享锁。
有以下两个规定:
作用:意向锁(Intention Locks)是表级锁。
原理:意向锁 在 读写锁 之上引入了 表级互斥锁 和 表级共享锁( IX/IS )。
通过引入意向锁,事务想要 对表加 X锁,需要先检测是否有其它事务对表加了 X/IX/S/IS 锁。如果加了就表示有其它事务正在使用这个表或者表中某一行,因此事务 加 X锁 失败。
一级封锁协议
事务修改数据时必须加 X 锁,直到事务结束才释放 X 锁。
解决丢失修改问题。
二级封锁协议
在一级的基础上,要求读取数据时必须加 S 锁,读取完马上释放 S 锁。
解决脏读问题。
三级封锁协议
在二级的基础上,要求读取数据时必须加 S 锁,直到事务结束才释放 S 锁。
解决不可重复读的问题。
在加锁阶段,事务只能加锁,不能解锁。直到事务释放第一个锁,就进入解锁阶段,此阶段 事务只能解锁,不能再加锁。
隐式锁定定义:MySQL 的 InnoDB 存储引擎采用两段锁协议,会根据隔离级别在需要的时候自动加锁,锁只有在执行 commit 或rollback 的时候才会释放,并且所有的锁在同一时刻被释放。
显示锁定定义:和隐式锁定相反。
READ UNCOMMITTED,简称 RU 。
一个事务未提交的数据,对其它事务是可见的。
READ COMMITTED,简称 RC 。
一个事务未提交的数据,对其它事务是不可见的。
REPEATABLE READ,简称 RR 。
一个事务多次读取同一数据的结果是一样的。
SERIALIZABLE,简称 SE 。
强制事务串行执行,多个事务互不干扰,不会出现并发一致性问题。
多版本并发控制(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现已提交读和可重复读这两种隔离级别。
原理:事务的修改操作会生成一个数据快照。在事务进行读取操作时,只能读取已经提交的快照。解决脏读和不可重复读问题。主要用于 RC 和 RR 级别。
SELECT 操作是快照读,不加锁。
增删改操作 是 当前读,加锁,读取数据库里最新的数据。
记 A->B 表示 A 函数决定 B函数,也表示 B 函数依赖于 A函数。
以下的学生课程关系的函数依赖为 {Sno, Cname} -> {Sname, Sdept, Mname, Grade},键码为 {Sno, Cname}。也就是说,确定学生和课程之后,就能确定其它信息。
Sno | Sname | Sdept | Mname | Cname | Grade |
---|---|---|---|---|---|
1 | 学生-1 | 学院-1 | 院长-1 | 课程-1 | 90 |
2 | 学生-2 | 学院-2 | 院长-2 | 课程-2 | 80 |
2 | 学生-2 | 学院-2 | 院长-2 | 课程-1 | 100 |
3 | 学生-3 | 学院-2 | 院长-2 | 课程-2 | 95 |
不符合范式的关系,会产生很多异常,主要有以下四种异常:
学生-2
出现了两次。课程-1
需要删除第一行和第三行,那么 学生-1
的信息就会丢失。范式理论是为了解决以上提到四种异常。
高级别范式的依赖于低级别的范式,1NF 是最低级别的范式。
属性不可分。
非主属性完全依赖于键码。
非主属性不传递依赖于键码。
Entity-Relationship,有三个组成部分:实体、属性、联系。
Eg:教学系统 ER 图