[mysql 详解]myqsl 锁机制 | mysql 技术论坛-江南app体育官方入口

锁是计算机协调多个进程或纯线程并发访问某一资源的机制。
保证数据并发访问的一致性、有效性

锁的运行

事务t在对某个数据对象(如表、记录等)操作之前,先向系统发出请求,对其加锁,加锁后事务t就对数据库对象有一定的控制,在事务t释放它的锁之前,其他事务不能更新此数据对象。

锁分类

按封锁类型

  • 排他锁(写锁、x锁)会阻塞其他事务读和写。
  • 共享锁(读锁、s锁)阻塞其他事务修改表数据。
  • 意向锁(innodb特有,本身是表级锁,是为了解决表级锁和行级锁之间的冲突)
    (意向锁为了方便检测表级锁和行级锁之间的冲突,故在给一行记录加锁前,首先给该表加意向锁。也就是同时加意向锁和行级锁。)
  • 间隙锁(innodb特有)

按封锁数据粒度

  • 行级锁(开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
  • 表级锁(开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。事务中查询非索引字段会锁表
  • 页级锁(销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。事务中查询索引字段会锁该行数据

活锁、死锁

采用封锁的方法可以有效防止数据的不一致性,单封锁本身会引起麻烦,就是死锁和活锁。

活锁

  • 定义:如果事务t1封锁了数据对象r后,事务t2也请求封锁r,于是t2等待,接着t3也请求封锁r。当t1释放了加载r上的锁后,系统首先批准t3的请求,t2只能继续等待。接着t4也请求封锁r,t3释放r上的锁后,系统又批转了t4的请求。这样的一直循环下去,事务t2就只能永远等待了,这样情况叫活锁。
  • 江南app体育官方入口的解决方案:采用先来先服务的队列策略。队列式申请。

死锁

  • 定义:当两个事务分别锁定了两个单独的对象,这时每一个事务都要求在另一个事务锁定的对象上获得一个锁,因此每一个事务都必须等待另一个事务释放占有的锁。这就发生了死锁了。
  • 预防江南app体育官方入口的解决方案:一次封锁法、顺序封锁法
  • 诊断死锁的方法:超时法、事务等待图法。

myisam 引擎 锁机制

  • 读锁
  • 写锁

详解:
(一)myisam表的读操作,不会阻塞其他用户对同一个表的读请求,但会阻塞对同一个表的写请求。
(二)myisam表的写操作,会阻塞其他用户对同一个表的读和写操作。
(三)myisam表的读、写操作之间、以及写操作之间是串行的。
(四)当一个线程获得对一个表的写锁后,只有持有锁线程可以对表进行更新操作。其他线程的读、写操作都会等待,直到锁被释放为止。
注意:
1. mysql认为写请求一般比读请求重要。
2. myisam在执行查询语句(select)前,会自动给涉及的所有表加读锁,在执行更新操作(update、delete、insert等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此用户一般不需要直接用lock table命令给myisam表显式加锁。

innodb引擎的锁机制

innodb和myisam不同

  • 支持事务
  • 只是行级锁

    锁分类

  • 共享锁
  • 排他锁
  • 意向锁(其中意向锁分为意向共享锁和意向排他锁
    详解:
    (一)行锁是针对索引的
    (二)行锁真正的作用范围

两个引擎的死锁对比

myisam表锁是无死锁的,这是因为myisam总是一次性获得所需的全部锁,要么全部满足,要么等待,因此不会出现死锁。但是在innodb中,除单个sql组成的事务外,锁是逐步获得的,这就决定了innodb发生死锁是可能的。

for update 锁级别

  • 开启事务后,使用for update 会锁表,按照索引字段查询除外。
  • 开启事务后,按照索引索引字段会锁住该行数据,其他不受影响。
  • for update 是写锁,读操作不会锁住。
  • 不开启事务,for update 不会锁任何数据。

乐观锁、悲观锁

乐观锁:

  • 使用数据版本(version)记录机制实现
  • 使用时间戳(timestamp)

悲观锁:

认为本次操作会发生并发冲突,所以一开始就对商品加上锁(select … for update),然后就可以安心的做判断和更新,因为这时候不会有别人更新这条商品库存。

参考

本作品采用《cc 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
网站地图