锁粒度

行锁

  • mysql的行锁是建立在索引上面的,如果对应的SQL语句没有使用索引,会进行全表扫描,同理会进行表锁。
  • 行锁会出现死锁,锁冲突的几率较低,并发也高,同理并发高,开销也就大。

表锁

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

死锁

假设事务A锁住了第12行数据,事务B锁住了第54行数据,这时事务A请求锁住第54行,就会阻塞到事务B释放第54行的锁,随后事务B也请求锁住第12行,同理,事务B也会阻塞到事务A释放第12行的锁,这时就会产生死锁,会报deadlock的错误。(表锁是针对表的,所以不会产生死锁)

锁冲突

假设事务A给表中的1-12行数据上锁,事务B也对1-12行上锁,锁不能共存就会出现锁冲突。

行锁的类型

共享锁可以和共享锁并存。
共享锁不能和排他锁并存。
排他锁不能和排它锁并存。

  • 共享锁(读锁)
    不会阻塞其他事务对同一表的读操作,会阻塞写操作
  • 排他锁(写锁)
    同时阻塞其他事务对同一表的读写操作

Myisam

  • 行锁:不支持
  • 表锁:支持(默认)
  • 加锁方法:

    • myisam在执行SELECT前,会自动给表加共享锁,再执行操作。
    • 执行UPDATE、DELETE、INSERT前会自动给表加排他锁。
    • 由于是表锁,所以myisam引擎总是一次性获取当前表的全部锁,这也是表锁不会出现死锁的原因。

Innodb

  • 行锁:支持(默认)
  • 表锁:支持
  • 加锁方法:

    • 执行UPDATE、DELETE、INSERT前会自动给数据集加排他锁。
    • SELECT默认不加锁。可通过语句给数据集增加共享锁和排它锁
    • 共享锁:SELECT field1,field2 FROM TEBLE WHERE .. LOCK IN SHARE MODE
    • 排它锁:SELECT field1,field2 FROM TEBLE WHERE .. FOR UPDATE

悲观锁、乐观锁

悲观锁:顾名思义,不信任其他任何操作,先上锁,保证数据唯一性。

乐观锁:每次读取数据时不认为其他操作会进行更新数据,所以不会先上锁,而是在执行时验证数据是否被更新过。可以使用版本号机制

最后修改:2019 年 02 月 13 日 11 : 29 AM
如果觉得我的文章对你有用,请随意赞赏