事务
ACID
原子性
隔离性
一致性
持久性
- 应对系统崩溃,可以用Redo Log恢复
AUTOCOMMIT:MySQL默认采用自动提交,不显示start transaction,每个查询都会被当成一个事务执行并自动提交
并发一致性问题
丢失修改
脏读
不可重复读
幻读
- insert操作引起
锁
锁粒度
- 行锁
- 表锁
锁类型
读写锁
- 互斥锁(X锁、写锁)
- 共享锁(S锁、读锁)
- 一个事务对数据A加了X锁,期间其他事务不能对A加任何锁
一个事务对数据A加了S锁,其他事务可以对A加S锁,但是不能加X锁
- 意向锁
- 可以更容易支持多粒度加锁
- IX/IS锁,表示一个事务想要再表中的某个数据行上加X/S锁
- 一个事务再获得某个数据行的S锁之前,必须先获得表的IS锁或更强的锁
- 一个事务在获得某个数据行的X锁之前,必须先获得表的IX锁
- 任意IS/IX锁之间都是兼容的
封锁协议
- 一级:事务T要修改A时必须加X锁,直到T结束才释放(解决丢失修改问题)
- 二级:在一级基础上事务T要读取A时必须加S锁,读取完立即释放锁(解决脏读问题)
- 三级:在二级的基础上,要求读取A时必须加S锁,直到事务结束才释放(解决不可重复读问题)
- 两段锁协议:加锁和解锁分两个阶段进行,保证可串行化调度
事务隔离级别
- 读未提交(RU)
- 读提交(RC)
- 可重复度(RR)
- 可串行化(Serializable)
多版本并发控制(MVCC)
版本号
- 系统版本号SYS_ID:每开启一个新事务时递增
- 事务版本号TRX_ID:事务开启时的系统版本号
ReadView
- 当前系统未提交的事务列表,以及最大ID和最小ID
快照读:SELECT,不需要进行加锁
当前读:INSERT、UPDATE、DELETE,需要加锁
SELECT时可以显式指定加锁
- select * from table where ? lock in share mode;(S锁)
- select * from table where ? for update;(X锁)
Next-Key Locks
- 可重复读级别下,使用MVCC+Next-Key Lock可以解决幻读
- Record Locks: 锁定一个记录上的索引
- Gap Locks:锁定索引之间的间隙,但是不包括索引本身
关系数据库
异常
- 冗余数据、修改异常、删除异常、插入异常
范式
- 为了解决异常
- 第一范式:属性不可分割
- 第二范式:非主属性完全依赖于键码
- 第三范式:非主属性不传递函数依赖于键码