多个事务更新同一行数据,如何加锁避免脏写

  1. 通过加锁,让多个事务更新一行数据的时候串行化。
  2. 一个事务A来更新数据的时候,会先看这行数据有没有人加锁,没人的话就会创建一个锁,里面包含了自己的trx_id和等待状态。数据和锁数据结构都在内存中。
  3. 一个事务B更新数据的时候,发现已经被加锁了。这个事务也会生成一个锁结构进行排队等待。锁结构包括trx_id和等待状态。
  4. 事务A更新完数据会释放掉的同时把事务B的等待状态修改为false。唤醒事务B。

    image.png

    共享锁和独占锁

  5. 独占锁,当有一个事务加了独占锁之后,其他事务再要更新这条数据,只能生成独占锁在后面等待。

  6. 共享锁,共享锁和共享锁不互斥,共享锁和独占锁互斥。

    哪些操作会加表级锁

  7. 多个事务并发更新数据的时候,会在行级别增加独占锁。 此时读取别的事务在更新的数据,有两种可能:① 基于MVCC机制进行事务隔离,读取快照版本 ② 查询的时候基于语法去加独占锁或者共享锁。

  8. 表级锁:在执行DDL操作(例如alter table),会阻塞执行增删改的操作,类似加上表级锁。innoDB存储引擎提供了自己的表级锁。

    行锁和表锁之间的关系

  9. 表锁分为两种:① 表锁 ② 表级的意向锁

  10. 表锁:可以用以下语法来加 ① Lock tables XXX read表级共享锁 ② Lock tables XXX write表级独占锁
  11. 如果事务在表里执行增删改操作,在行级加独占锁,在表级加意向独占锁。如果事务在表里查询,会在表级加意向共享锁。

image.png