关于数据库事务和锁的必会知识点,你掌握了多少? (3)

在这里插入图片描述

行锁实现方式:INnoDB的行锁是通过给索引上的索引项加锁实现的,如果没有索引,InnoDB将通过隐藏的聚簇索引来对记录进行加锁。

InnoDB行锁主要分三种情况:

Record lock:对索引项加锁

Grap lock:对索引之间的“间隙”、第一条记录前的“间隙”或最后一条后的间隙加锁。

Next-key lock:前两种放入组合,对记录及前面的间隙加锁。

InnoDB行锁的特性:如果不通过索引条件检索数据,那么InnoDB将对表中所有记录加锁,实际产生的效果和表锁是一样的。

MVCC不能解决幻读问题,在可重复读隔离级别下,使用MVCC+Next-Key Locks可以解决幻读问题。

什么是数据库的乐观锁和悲观锁,如何实现?

乐观锁:系统假设数据的更新在大多数时候是不会产生冲突的,所以数据库只在更新操作提交的时候对数据检测冲突,如果存在冲突,则数据更新失败。

乐观锁实现方式:一般通过版本号和CAS算法实现。

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。通俗讲就是每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁。

悲观锁的实现方式:通过数据库的锁机制实现,对查询语句添加for updata。

什么是死锁?如何避免?

死锁是指两个或者两个以上进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象。在MySQL中,MyISAM是一次获得所需的全部锁,要么全部满足,要么等待,所以不会出现死锁。在InnoDB存储引擎中,除了单个SQL组成的事务外,锁都是逐步获得的,所以存在死锁问题。

如何避免MySQL发生死锁或锁冲突:

如果不同的程序并发存取多个表,尽量以相同的顺序访问表。

在程序以批量方式处理数据的时候,如果已经对数据排序,尽量保证每个线程按照固定的顺序来处理记录。

在事务中,如果需要更新记录,应直接申请足够级别的排他锁,而不应该先申请共享锁,更新时在申请排他锁,因为在当前用户申请排他锁时,其他事务可能已经获得了相同记录的共享锁,从而造成锁冲突或者死锁。

尽量使用较低的隔离级别

尽量使用索引访问数据,使加锁更加准确,从而减少锁冲突的机会

合理选择事务的大小,小事务发生锁冲突的概率更低

尽量用相等的条件访问数据,可以避免Next-Key锁对并发插入的影响。

不要申请超过实际需要的锁级别,查询时尽量不要显示加锁

对于一些特定的事务,可以表锁来提高处理速度或减少死锁的概率。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjfzp.html