InnoDB的锁

​当遇到对临界资源进行并发访问的时候,一方面要最大化的性能,另一方面还要保障数据的一致性,而锁机制可以很好的达成这样的效果。本文主要介绍InnoDB中的锁。

​InnoDB中锁按照粒度来分可分为行级锁与表级锁。行级锁通过索引上的索引项实现,其中包含共享锁与排他锁:

  • 共享锁(S):允许事务读一行数据。
  • 排他锁(X):允许事务delete或update一行数据

S与S兼容,其它情况都不兼容。在使用索引进行检索时,InnoDB会加上S锁,这一点可能会引起大量的锁冲突,需要注意。

表级锁包含意向共享锁和意向排他锁:

意向共享锁(IS):事务想要获得一个表中某几行的共享锁。

意向排他锁(IX):事务想要获得一个表中某几行的排他锁。

意向锁不会阻塞除全表扫描外的请求。

​可以通过三张表查询现在事务与锁的状态:

  • INNODB_TRX:现在正在执行的事务的情况。
  • INNODB_LOCKS:现在锁的情况。
  • INNODB_LOCK_WAITS:现在被阻塞的事务与锁情况。

如果在锁不兼容的情况下需要读取行的数据,就需要使事务读取行的一个快照数据。原理是通过Undo段回滚数据。一行可能有多个版本的快照数据,此时就需要多版本并发控制技术(MVCC)。在read committed的书屋隔离条件下,InnoDB使用非锁定的一致性读,总是读取被锁定行的最新一份快照数据,而在Repeatable的事务隔离级别下,InnoDB则是读取事务开始前的快照数据版本。

​ 在InnoDB中行锁的算法有3种,分别是:

  • Record Lock:单个行记录上的锁;
  • Gap Lock:间隙锁,锁定除记录本身的范围;
  • Next-Key Lock:锁定一个范围并锁定记录本身,是默认的算法。

​当然锁虽然可以提高并发,满足事务的隔离性需求,但锁也带来了问题。

  • 丢失更新:事务的更新操作丢失。这是件非常严重的问题,尤其是在金融领域。想在数据库层面解决这个问题,就需要将操作串行化,按次序执行。
  • 脏读:读到了未提交的数据,违反了隔离性。解决方案是将事务隔离级别提升到read uncommit。
  • 不可重复读:一个事务多次读取同一数据期间数据被其他事务修改,导致两次读取的数据不一样。解决方案是将事务隔离级别提升到Read Repeatable。
  • 死锁:A等待B,B等待A。解决方案是进行回滚操作,往往InnoDB会解决大多数的死锁。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值