MySQL数据库的锁(什么是数据库的锁?什么是乐观锁和悲观锁?什么是死锁?如何避免?)

什么是数据库的锁?

    当数据库有并发事务的时候,保证数据访问顺序的机制称为锁机制。

数据库的锁与隔离级别的关系?

隔离级别实现方式
未提交读总是读取最新的数据,无需加锁
提交读读取数据时加共享锁,读取数据后释放共享锁
可重复读读取数据时加共享锁,事务结束后释放共享锁
串行化锁定整个范围的键,一直持有锁直到事务结束

数据库锁的类型有哪些?

按照锁的粒度可以将MySQL锁分为三种:

MySQL锁类别资源开销加锁速度是否会出现死锁锁的粒度并发度
表级锁不会
行级锁
页面锁一般一般不会一般一般

MyISAM默认采用表级锁,InnoDB默认采用行级锁。

从锁的类别上区别可以分为共享锁和排他锁。

  • 共享锁:共享锁又称读锁,简写为S锁,一个事务对一个数据对象加了S锁,可以对这个数据对象进行读取操作,但不能进行更新操作。并且在加锁期间其他事务只能对这个数据对象加S锁,不能加X锁。
  • 排他锁:排他锁又称为写锁,简写为X锁,一个事务对一个数据对象加了X锁,可以对这个对象进行读取和更新操作,加锁期间,其他事务不能对该数据对象进行加X锁或S锁。

它们的兼容情况如下:
在这里插入图片描述

MySQL中InnoDB引擎的行锁模式及其是如何实现的?

行锁模式
    在存在行锁和表锁的情况下,一个事务想对某个表加X锁时,需要先检查是否有其他事务对这个表加了锁或对这个表的某一行加了锁,对表的每一行都进行检测一次这是非常低效率的,为了解决这种问题,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁,两种意向锁都是表锁。

  • 意向共享锁:简称IS锁,一个事务打算给数据行加共享锁前必须先获得该表的IS锁。
  • 意向排他锁:简称IX锁,一个事务打算给数据行加排他锁前必须先获得该表的IX锁。有了意向锁,一个事务想对某个表加X锁,只需要检查是否有其他事务对这个表加了X/IX/S/IS锁即可。锁的兼容性如下:

在这里插入图片描述
行锁实现方式: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锁对并发插入的影响。
  • 不要申请超过实际需要的锁级别,查询时尽量不要显示加锁。
  • 对于一些特定的事务,可以表锁来提高处理速度或减少死锁的概率。

推荐阅读:
Java面试题(2022最新持续更新版)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值