什么是锁

MyISAM中使用表锁

InnoDB使用行锁

 

InnoDB存储引擎中的锁

  • 两种标准的行级锁:

共享锁(S),允许事务读数据

排他锁(X),允许事务删除/更新数据

  • 意向锁:

下一行将被请求的锁的类型

意向共享锁;意向排他锁

意向锁只会阻塞全表扫的请求

通过INFORMATION_SCHEMA架构下的INNODB_TRX, INNODB_LOCKS, INNODB_LOCK_WAITS可以查看当前事务以及锁信息

  • 一致性非锁定读(默认):

通过行多版本控制的方式读取数据

如果读取的数据上了X锁,则读取行的一个快照版本

快照数据通过Undo来实现

READ COMMITTED:使用最新的快照数据

REPEATABLE READ:使用事务开始时的数据

数据库——锁

  • 对读取数据枷锁:

SELECT … FOR UPDATE:加X锁

SELECT … LOCK IN SHARE MODE:加S锁

  • 自增长和锁:

自增长计数器

自增长值得列必须是索引得第一个列

AUTO-INC Locking:插入使自增长计数器值加1赋予自增长列

锁在完成对自增长值插入的SQL语句后释放

提供轻量级互斥量的自增长实现机制,提高自增长值插入性能(互斥量mutex)

  • 外键列:

自动添加索引,避免表锁

对父表读取,采用S锁

 

 

锁算法

Record Lock:单行记录上的锁(锁住索引记录)

Gap Lock:锁定一个范围,但不包含记录本身

Next-Ket Lock:锁定一个范围,并且锁定记录本身

 

锁问题

1.丢失更新

T1查询数据

T2也查询该数据

User1修改记录更新数据库并提交

User2也修改记录并提交

User1的更新操作丢失

解决方式:对记录加上X锁

 

2.脏读

读取到未提交的数据

大部分数据库至少为READ COMMITTED

InnoDB默认的事务隔离级别为READ REPEATABLE

 

3.不可重复读(Phantom Problem)

同一个事务内多次读同一个数据值不同(由于另一个事务提交了数据)

解决方式:Next-Key Lock

 

 

阻塞

使用Mutex数据结构实现锁

使用mutex_enter申请资源;mutex_exit释放资源

可以设置等待超时是否对进行中的事务进行回滚(默认不回滚)

 

 

死锁

发现死锁后,立马回滚一个事务

Oracle常见死锁原因:没有对外键添加索引

 

锁升级

将当前锁的粒度降低

把一个表的1000个行锁升级为页锁/页锁升级为表锁

防止使用太多内存维护锁

  • 锁升级的情况:

1.一个对象持有的锁数量超过阈值

2.锁资源占用的内存超过阈值

相关文章: