2016 - 2024

感恩一路有你

mysql行锁和表锁面试 关于MySQL中的表锁和行锁?

浏览量:2459 时间:2021-03-11 05:54:12 作者:admin

关于MySQL中的表锁和行锁?

1. 程序中非数据库交互操作导致事务挂起

将接口调用或者文件操作等这一类非数据库交互操作嵌入在 SQL 事务代码之中,那么整个事务很有可能因此挂起(接口不通等待超时或是上传下载大附件)。

2. 事务中包含性能较差的查询 SQL

事务中存在慢查询,导致同一个事务中的其他 DML 无法及时释放占用的行锁,引起行锁等待。

3. 单个事务中包含大量 SQL

通常是由于在事务代码中加入 for 循环导致,虽然单个 SQL 运行很快,但是 SQL 数量一大,事务就会很慢。

4. 级联更新 SQL 执行时间较久

这类 SQL 容易让人产生错觉,例如:update A set ... where ...in (select B) 这类级联更新,不仅会占用 A 表上的行锁,也会占用 B 表上的行锁,当 SQL 执行较久时,很容易引起 B 表上的行锁等待。

5. 磁盘问题导致的事务挂起

极少出现的情形,比如存储突然离线,SQL 执行会卡在内核调用磁盘的步骤上,一直等待,事务无法提交。

综上可以看出,如果事务长时间未提交,且事务中包含了 DML 操作,那么就有可能产生行锁等待,引起报错。

mysql怎么查看是表锁还是行锁?

MyISAM不支持事物,所以这些隔离级别是没有意义的。然后再说一下这些隔离级别和锁之间的关系(如在InnoDB中,支持行级锁):首先一个事物由begin开始,由commit(成功执行)或rollback(执行失败,需要回滚)终止,所以考虑事物问题的时候要考虑到事物的整个生命周期,对同一行数据的加锁解锁操作是有可能多次执行的,因此传统的2 Phase Locking(2PL,两阶段锁)才会有很多变种,最简单的是只要先统一上锁,后统一释放锁就可以了,不用考虑释放锁的时间,最严格的是所有的锁一旦加上之后,必须要等到事物commit或rollback后才可以释放。举个例子,有一行数据 a,有两个事物T1,T21.read uncommittedT1对a进行写操作,写之前加了写锁,写之后但是commit前释放了写锁,这时候T2是可以读a的,由于T1还没有commit,所以T2就发生了read uncommitted的情况。2.read committed还是1中的情况,如果T1把a的写锁一直保持到T1 commit成功之后再释放,那么T2在T1 commit之前都是不可以读a的,就可以避免read uncommitted,这就是read committed。但是这种隔离级别下,如果t1插入了一个以前不存在的新行b,t2是可以读的,就造成了幻读的情况。3.repeatable read为了避免幻读,可以加谓词锁延迟新行的添加,比如T2要读大于5的行,那么就加个谓词锁,使得大于5的行不能被添加进去,这种实现基本上也是实现了serializable read基于锁的事物只是一种方法,一般被成为悲观并发控制。此外,还有:乐观并发控制:执行读写的时候不加锁,commit的时候检测是否有冲突,若没有冲突commit成功,否则需要rollback,值得注意的是,虽然读写的时候没有加锁,但是检测的时候是要加锁的,否则2个冲突的事物可能同时检测成功,这一点绝大多数材料里都没有指出。MVCC:给每个数据一个版本号,读的时候完全不需要锁,写的时候看具体实现,可以选择乐观并发控制,也可以选择悲观并发控制,这种实现很容易实现snapshot isolation(也是一种隔离级别,只不过没有以上几个名气大,可以保证每个事物可以看到一个在它发生之前的数据库完整实例)。

mysql行锁和表锁面试 update锁表还是锁行 insert是表锁还是行锁

版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。