数据库原理
1.事务
ACID
原子性
一致性
隔离性
持久性
2.并发一致性问题
修改覆盖(写写之间并发)
读取其他事务修改的数据:t1修改,t2修改,t2修改覆盖t1修改,t1最后读取t2修改的数据
脏读(写读之间并发)
读取其他事务未提交的数据:t1修改未提交,t2读取,t1回滚,t2读取了t1未提交的数据
不可重复读
同一个事务读取数据行值前后不一致:t1读取,t2修改,t1再次读取,前后读取不一致
幻读
同一个事务读取范围值前后不一致:t1读取范围值,t2在此范围内插入数据,t1再次读取范围值不一致
3.封锁
封锁类型
排他锁X/共享锁S
SS锁兼容,其他均不兼容;读读锁兼容,读写、写写锁之间不兼容
意向锁IX/IS
事务T对表A加锁时,需要判断是否有其他事务对表A或表A中任意一行加锁,需要全表扫描
意向锁规定,当事务对数据行加锁时,首先获得表的意向锁,事务T对表A加锁时,就不需要全表扫描了
封锁协议
一级封锁协议
事务T对数据行写操作需要获得X锁(可以解决写写之间并发,修改覆盖)
二级封锁协议
事务T对数据行读操作需要获得S锁(可以解决读写之间并发,脏读:其他事务写操作未提交,不释放X锁,T读操作无法获得S锁,直到其他事务提交)
三级封锁协议
事务T对数据行读操作需要获得S锁,直到事务结束释放(可以解决不可重复读:T不释放S锁,其他事务无法获得X锁进行写操作。)
4.事务隔离性
未提交读
Read Uncommited
提交读
Read Commited
可重复读
Repeatable Read
可串行化
Serializeable
5.多版本并发控制MVCC
Undo日志
MVCC使用到的快照存储在Undo-log中,记录数据行的所有操作快照,通过回滚指针将快照链接。
隐藏的列
每行记录后面保存着两个隐藏的列,创建版本号、删除版本号
创建版本号:创建一个数据行快照时的系统版本号
删除版本号:如果快照的删除版本号大于当前系统版本号,说明快照有效,否则无效
版本号
系统版本号:自增序号,每开启一个事务,系统版本号加一
事务版本号:事务开始时系统版本号
实现方式
select
创建版本号 < 事务T版本号 < 删除版本号
读取操作事务T所要读取的数据行创建版本号要小于T的创建版本号,否则说明其他事务对数据行有修改,产生脏读
同时此数据行的删除版本号要大于T的版本号,否则表示此数据行已经删除
insert
将当前系统版本号作为数据行快照的创建版本号
delete
将当前系统版本号作为数据行的删除版本号
update
将当前系统版本号作为数据行的删除版本号,将当前系统版本号作为更新后的数据行的创建版本号,可以理解为先delete后insert
快照读
读取快照中的数据,减少加锁带来的开销
select * from table ...
当前读
读取最新的数据,需要加锁
select * from table share in mode
select * from table for update
insert
delete
update
6.Next-key Lock
Record Lock:记录行的索引加锁
Gape Lock:索引间隙加锁
Next-key Lock:以上两者结合
Next-key Lock + MVCC 解决幻读