mysql行锁和表锁面试 关于MySQL中的表锁和行锁?
关于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是表锁还是行锁
版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。