InnoDB引擎的行锁和表锁

mysql常用引擎有MYISAM和InnoDB,MYISAM不支持行锁,InnoDB支持行锁和表锁。mysql的行锁是通过索引加载的,所以说行锁是加在索引行上的。要是对应的SQL语句没有走索引,则会全表扫描,行锁则无法实现,取而代之的是表锁。

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

  • 锁冲突

比如事务A将某几行上锁后,事务B又对其上锁,锁不能共存否则会出现锁冲突。(共享锁可以共存,共享锁和排它锁不能共存,排它锁和排他锁也不可以)

  • 死锁

比如两个事务,事务A锁住了15行,同时事务B锁住了610行,此时事务A请求锁住610行,就会阻塞直到事务B施放610行的锁,而随后事务B又请求锁住15行,事务B也阻塞直到事务A释放15行的锁。死锁发生时,会产生Deadlock错误。(表锁是对表操作的,所以自然锁住全表的表锁就不会出现死锁)

  • 行锁的类型

行锁分 共享锁 和 排它锁。

    • 共享锁(读锁) 当一个事务对某几行上读锁时,允许其他事务对这几行进行读操作,但不允许其进行写操作,也不允许其他事务给这几行上排它锁,但允许上读锁。

例:select a1 from test where a1>1 lock in share mode;

    • 排它锁(写锁)

当一个事务对某几个上写锁时,不允许其他事务写,但允许读。更不允许其他事务给这几行上任何锁。包括写锁。

例:select a1 from test where a1 >1 for update;

  • 行锁的实现要注意
    • 行锁必须有索引才能实现,否则会自动锁全表,那么就不是行锁了。
    • 两个事务不能锁同一个索引 如: 1、select a1 from test where a1>2 for update; 2、select a1 from test where a2<2 for update; 要是1先执行2接着执行2就会阻塞但是把索引字段换成其他的就不会阻塞了(换成其他索引锁住的行不能和1索引锁住的行有重复)

3.insert ,delete , update在事务中都会自动默认加上排它锁。

鲁ICP备16017569号-2