数据库小结
事务
事务是构成单一工作单元的操作的集合。就是一组不可分割的随数据库的操作。
事务的ACID性质
原子性:事务为最小工作单元,不可分割。要么全部执行,要么执行失败,所有操作回滚。
一致性:事务执行前后数据均是合理的状态,不会遭到破坏。
隔离性:并行事务互不干扰。
持久性:被提交的事务永久记录于数据库中。
事务并发的问题
丢失更新:两事务并行,先后读取到数据A,第一个事务对A修改并提交,但第二个事务并不知道A被修改,对A原始值修改并提交,导致A的第一次修改被覆盖。
脏数据:第一个事务对A做修改,第二个事务读取A,但第一个事务之后取消修改,第二个事务读取到错误数据。
不可重复度问题:事务a读取数据A,之后事务b修改数据A,a再一次读取A则得到不同结果。
幻读:T1 读取某个范围的数据,T2 在这个范围内插入新的数据,T1 再次读取这个范围的数据,此时读取的结果和和第一次读取的结果不同。
破坏事务隔离性导致上诉问题。
封锁
排他型封锁(X锁、写锁):事务T对数据R实现了X锁,则解除封锁前R不会被加以任何类型锁。实现成功则事务T可读写R,否则事务进入等待队列。直到获准X锁。
共享型封锁(S锁、读锁):事务T对数据R实现S锁,解除封锁前允许其他事务对R添加S锁,但不能添加X锁。成功则可以读取R。否则进入等待队列。直到获准S锁。
封锁粒度:表示封锁对象的大小。
三级封锁协议:
一级:事务在修改数据前必须添加X锁,结束后释放,读取数据时可不加锁。
可以防止丢失更新问题
二级:在一级基础上,读取数据前必须添加S锁,读取数据完成后释放。
可以防止丢失更新、读脏数据。
三级:在二级基础上,读取完成后不释放S锁,直到事务结束后释放。
可以防止丢失更新、读脏数据、不可重复读。
隔离级别
可以读取未提交数据:允许事务读取已提交和未提交的数据。
读提交数据:只允许读取已提交的数据。
事务在更新某数据的时,必须先对其加行级排他锁,直到事务结束才释放。
可重复读:只允许读取已提交数据,且两次读同一数据时不许修改数据。
事务在读取数据时加行级共享锁,事务结束后释放。
事务修改数据时加行级排他锁,事务结束后释放。
可串行化:事务并发执行时,保证并发调度可串行化。
事务在读取数据时,必须先对其加表级共享锁 ,直到事务结束才释放。
事务在更新数据时,必须先对其加表级排他锁 ,直到事务结束才释放。
多版本并发控制
多版本并发控制(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于可重复读这两种隔离级别。而未提交读隔离级别总是读取最新的数据行,无需使用 MVCC。可串行化隔离级别需要表级锁,单纯使用 MVCC 无法实现。
MVCC的实现,通过保存数据在某个时间点的快照来实现的。这意味着一个事务无论运行多长时间,在同一个事务里能够看到数据一致的视图。根据事务开始的时间不同,同时也意味着在同一个时刻不同事务看到的相同表里的数据可能是不同的。
在每一行数据中额外保存三个隐藏的列:当前行创建时的版本号和删除时的版本号,还有一列称为回滚指针,指向用于回滚的记录,用于事务回滚。这里的版本号是系统版本号,每开始新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询每行记录的版本号进行比较。、
查询:事务的版本号大于数据的创建版本号,小于删除版本号,保证事务执行时数据存在并且正确。
数据库设计
关系模式设计的不好,将会出现数据冗余问题。
未完
参考:
https://cyc2018.github.io/CS-Notes/#/notes/数据库系统原理?id=未提交读(read-uncommitted)
《数据库系统教程》施伯乐