MySQL——InnoDB行锁

它的行锁分为三种情形:

  1. Record lock:对索引项加锁。
  2. Gap lock:对索引项之间的“间隙”、第一条记录钱的“间隙”或最后一条记录后的“间隙”加锁。
  3. Next-key lock:前两种的组合,对记录及其前面的间隙加锁。

InnoDB行锁是通过给索引上的索引项加锁实现时,如果没有索引,InnoDB将通过隐藏的聚簇索引来对记录加锁。
简单地说:如果不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,实际效果跟表锁一样。
具体如下:

  • 在不通过索引条件查询时,InnoDB会锁定表中的所有记录。
  • 如果是使用相同的索引键,会出现锁冲突。
  • 当表有多个所以呢的时候,不同的事务可以使用不同的索引锁定不同的行,不论是使用主键做一年、唯一索引或普通索引。
  • 即便在条件中使用了索引字段,但是否使用索引来检索输是有MySQL通过判断不同执行计划的代价来决定的,如果全表扫描效率更高,就不会使用索引,这时候就会对所有记录加锁。

Next-Key锁
1、当使用范围条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁。对于键值在条件范围内但并不存在的记录,叫做“间隙”,也会对这个“间隙”进行加锁。
举例:
select * from emp where empid>100 for update;
这条语句会将empid大于100的记录全部加锁,即便不存在。
使用目的:防止幻读;满足其恢复和复制的需要。
注:除了通过范围条件加锁时使用Next-Key锁外,如果使用相等条件请求一个不存在的记录加锁,它也会使用Next-Key锁!
假设select * from emp where empid=102 for update;(102不存在),此时,其他session若想插入202(不存在),则会发生锁等待。

什么时候使用表锁:
第一种情况是:事务需要更新大部分或全部数据,表又比较大,如果使用默认的行锁,不仅这个事务执行效率低,而且可能造成其他事务长时间锁等待和锁冲突,这种情况下可以考虑使用表锁来提高改事务的执行速度。
第二种情况是:事务涉及到多个表,比较复杂,很可能引起死锁,造成大量事务回滚。这种情况也可以考虑一次性锁定事务涉及的表,从而避免死锁,减少数据库因事务回滚带来的开销。
如果出现以上两种事务太多,应该考虑使用MyISAM表。

此外,在使用表锁要注意以下两点:
1、使用LOCK TABLES加锁时,进当autocommit=0、innodb_table_locks=1(默认设置)时,InnoDB层才能知道MySQL加的是表锁,MySQL Server层才能够感知InnoDB加的行锁,而InnoDB才能自动识别涉及表级锁的死锁。
2、事务结束前,不要对UNLOCK TABLES释放表锁,因为会隐含地提交事务;COMMIT或ROLLBACK并不能释放用LOCK TABLES加的表级锁,必须用UNLOCK TABLES释放表锁。正确的语法:
set autocommit=0;
lock tables t1 write,t2 read,…;
[do something]
commit;
unlock tables;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值