赞
踩
乐观锁:在数据表增加一个 “version” 字段,数据行每更新一次,其version值加一。当需要提交更新时,对比数据行的当前版本号与同一事务中第一次读操作取出来的版本号,一致则更新,不一致则说明数据已过期,不更新,并且返回错误给用户,交由用户判断。
表级锁和行级锁中都有以下这两种锁:
意向锁
二者冲突。InnoDB为了让行级锁与表级锁共存,又加入了意向锁(粒度属于表锁)。当一个事务要对某一行加行级锁时,它需要先给表加上意向锁(加共享锁就要加意向共享锁,加排他锁就要加意向排他锁)。原因如下:
不加意向锁:事务A对某一行加上共享锁后(事务A要读这一行),事务B想要对这个表加上排他锁(事务B要写这个表)。由于排他锁不允许其他事务读或者写这个表,因此事务B需要检查每一行是否有共享锁或者排他锁,而逐行检查带来非常大的开销。
加意向锁:事务A想对这个表加上意向共享锁,然后对目标行加上共享锁,随后事务B想要对这个表加上排他锁,此时事务B只需要检查表上是否有意向共享锁或者意向排他锁即可,如果有其一就不可以加锁,需要等待意向锁释放,如果都没有就可以加锁。
意向锁是InnoDB自动加的,不需用户干预。
间隙锁
间隙锁(Next-Key锁)是指当我们用范围条件检索数据且申请锁时,不仅会给范围条件内已有的数据记录加锁,而且还给那些处于范围条件内但不存在的数据记录(间隙)加锁,目的是防止幻读。如果不使用间隙锁,则执行上述事务时,另一个事务插入新的数据记录且处于范围条件内,就会导致幻读。而加上间隙锁则可以阻止后者在此范围内插入新数据。(春招面试题,当时我没有看过这个锁,只答成了锁表,失败)但是如果应用场景下有大量插入操作时,需要尽量避免使用间隙锁,否则会阻塞大量的插入请求。
死锁
可以认为数据记录或者数据表是一种资源,死锁的一个典型场景:事务A先申请数据行1的共享锁,然后申请数据行2的排他锁。事务B先申请数据行2的共享锁,后申请数据行1的排他锁。结果事务A和B申请完共享锁后,申请排他锁的请求都被对方block住了,导致死锁。(表级锁也有这种情况)
数据库自动加锁
程序员一般不需要关心表锁
现在大多数情况都是使用MySQL的InnoDB引擎,InnoDB支持行锁
注意:InnoDB行锁是通过给索引上的索引节点加锁来实现的,只有通过索引条件检索数据,InnoDB才使用行级锁,否则InnoDB将使用表锁,即where 后面的字段里必须包含有索引的字段(主键索引、辅助索引),然后把行级锁加载索引节点上。
一般情况下数据库自动加的锁是够用的。然而当我们要用到数据库事务时,有可能需要手动加锁确保事务的正确执行。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。