美文网首页Mysql
Mysql-InnoDB引擎的行锁

Mysql-InnoDB引擎的行锁

作者: 都是浮云啊 | 来源:发表于2018-09-28 08:57 被阅读7次

前言:

Mysql常用的引擎有MYISAMInnoDB,而InnoDBMysql5.1版本之后默认的引擎(之前是MYISAM),MYISAM不支持行锁,而InnoDB支持行锁和表锁(当然还有很多异同点)

目录

  1. 行锁和表锁
  2. 行锁的类型
  3. 行锁的实现

1. 行锁和表锁

在Mysql的InnoDB引擎支持行锁,与Oracle不同,mysql的行锁是通过索引加载的,即行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描,行锁就无法实现取而代之的是表锁。

表锁: 不会发生死锁,发生锁冲突几率高,并发低
行锁: 会出现死锁,发生锁冲突几率低,并发高

  • 锁冲突:事物A将某几行上锁后,事物B又对其上锁,锁不能共存否则会导致锁冲突(共享锁可以共存,共享锁和排他锁不能共存,排他锁和排它锁也不能)
  • 死锁:事物A锁住了1-5行,同时事物B锁住了6-10行,此时事物A请求锁住6-10,就会堵塞直到事物B释放6-10行锁,事物B请求锁住1-5,事物B也堵塞直到事物A释放1-5行锁,死锁发生时会产生DeadLock错误。
    ps:锁是对表操作的,所以自然锁住全表就不会出现死锁。

2. 行锁的类型

行锁分共享锁和排它锁(也称之为读锁和写锁)

  • 共享锁(读锁):共享锁可以与共享锁共存,都是读又不写。当一个事物对某几行上读锁时,允许其他事物对着几行进行读操作,但是不允许写操作也不允许其他事物给这几行上排它锁,但是允许上读锁。
  • 排它锁(写锁):当一个事物对某几个上写锁时,不允许其他事物写,但允许读。更不允许其他事物给这几行上任何锁。

共享锁的写法:lock in share mode
如:select math from red_envelope where num>60 lock in share mode;

排它锁的写法:for update
如:select math from red_envelope where num>60 for update;

3. 行锁的实现

  1. 行锁必须有索引才能实现,否则会自动锁全表,那么久不是行锁了。
  2. 两个事物不能锁同一个索引,例如:
    事物A先执行 select math from red_envelope where num>60 for update;
    事物B再执行 select math from red_envelope where num<60 for update;
    这样的话,事物B是堵塞的。如果事物B把math索引换成其他索引就不会堵塞
  3. INSERT、DELETE、UPDATE在事物中都会自动默认加上排它锁
会话1 会话2
begin;select math from red_envelpe where math>60 for update; begin;update red_envelope set math=99 where math=68;堵塞···

会话相当于用户的操作:
如上表:会话1先把math>60的行上上排它锁,会话2试图把math=68的行进行修改,math=68处于math>60中,所以是已经被锁的,会话2操作时就会堵塞等待会话1把锁释放,当commit或者程序结束时就会释放锁。

相关文章

网友评论

    本文标题:Mysql-InnoDB引擎的行锁

    本文链接:https://www.haomeiwen.com/subject/jsjuoftx.html