锁的类别
1.表锁(MyISAM)
2.行锁(InnoDB)
S 锁:共享锁,允许事务读取一条数据
X锁:排他锁,允许事务删除或更新一条数据
S锁仅与S锁兼容,X锁与所有锁都不兼容
InnoDB 锁
一致性非锁定读
InnoDB 如果要读取某一行的数据,如果该行正在进行DELETE 或者 UPDATE 操作,不会等待该行锁释放,而是通过undo去读取一个快照,一行数据可能有多个快照,这就是MVCC(多版本并发控制),提高并发。
在 READ CIMMITED 隔离级别下:读取的总是最新版本的快照(造成不可重复读),违法了隔离性
在 REPEATABLE READ 隔离级别下:读取的总是事务开始的数据快照(解决了不可重复读的问题,既可重复读)
一致性锁定读
两种实现方式:
1)SELECT...FOR UPDATE 给读取的行加X锁
2) SELECT...FOR SHARE MODE 给读取的行加S锁
两种方式不影响非一致性读,在事务提交时自动释放
自增长和锁
1)以前用表锁的AUTO-INC Locking 实现,不会等事务提交,只要插入就会释放,存在性能问题
外键与锁
外键会自动加上索引,避免表锁
锁的算法
Record Lock :单个行记录上的锁
Gap Lock:间隙锁,锁定一个范围,但不包括该行记录
Next-Key Lock:Gap Lock + Record Lock,锁定一个范围,并且锁定该记录
InnoDB 采用Next-Key Lock 算法,当查询的索引列有唯一属性时,会降级为Recod Lock ,只锁定该行,不锁定范围
锁带来的问题
1.脏读:读取到未提交的数据(设置为READ COMMITED解决)
2.不可重复读:一次事务中两次读取到的数据不一致,违反了隔离性(设置为 REPEATABLE READ ,采用 Next-Key Lock锁定一段个范围,在这个范围内的插入都是阻塞的。解决)
3.丢失更新:物理不会出现,逻辑出现。
阻塞
阻塞超时,不会回滚数据
死锁
死锁是因为两个事务争抢同一个资源而造成相互等待。
解决死锁:
1):回滚所有事务,性能急剧下降,不可接受
2):超时回滚:也会有性能影响
3):当前数据库普遍采用 wait-for graph (等待图)实现,检测死锁,如果存在就选择undo段最小的事务进行回滚
网友评论