mysql 锁的使用

在同一时刻修改表中的同一数据就会存在并发问题,如何处理这样的问题呢,mysql 提供了2中锁的实现方式

  • 行锁
  • 表锁

我们在操作表的时候一般会涉及到以下几种情况

  • 读取数据
  • 写数据
  • 并发,同一时刻写数据
  • 并发,同一时刻读数据
  • 并发,同一时刻读写数据

为了解决以上的问题
在读数据的时候会加读锁,同一时刻只允许其它用户读取数据,阻塞写操作,保证我们正在读取的数据不会被修改。而实际上 Mysql 采用 MVCC 多版本并发控制,对于 select 是不需要加锁的。

在写数据的时候会加写锁,阻塞其它所有的读写操作,这才能保证其它用户不会读取到正在写的数据。

行锁
我们举个例子,假设现在有 A、B 2个用户,假设 A 先发生
T1 - T3 时刻 (修改完成需要的时间),A 在修改一个 user 表 id 为 1 的数据,将其 age = age + 1, name = ‘long’。
T2 时刻,B 在读取一个 user 表 id 为 1 的数据
那么 A 在 T1 - T3 时刻会对 user 表 id 为 1 的那条数据加写锁,而 B 则在 T2 时刻阻塞,直到A 操作完成,B 在读取到的就是更新后的数据。

试想一下这种情况如果没有读写锁,是不是 B 用户可能会读到 A 用户修改了一半的数据,拿到的结果可能会是 age = age + 1。或者 name = ‘long’。这样的错误数据。

表锁
读操作对表加读锁,阻塞其它用户写,允许其它用户读。
写操作对表加写锁,锁住整张表,其它用户所有的读写操作全部阻塞。

锁选用及优缺点
因为加锁也需要消耗资源,各种锁的操作,包括获得锁,检查锁,释放锁都会增加系统开销。所以锁的粒度越小资源消耗越高,但是并发性也越高。

如果可能存在大量的并发读写,采用表锁显然是不合适的,一个写操作阻塞后续所有的读写操作,导致请求堆积系统崩溃。这个时候采用行锁效果更好,因为同一时刻对于表有大量的读写操作精确到了某一行或者某一段区间,所以锁数据也是某一行和某一段数据。剩下个的数据依然可以并发访问读写。其实在这个地方有的点就是,每次修改的数据能精确到某一行并发性能最好,或者就是尽量的减少其修改的范围。

如果只有大量的读,极少的写,这个时候采用表锁是极好的,锁的资源消耗大大降低,偶尔存在的写锁,就lock 整张表就是。

你可能感兴趣的:(mysql 锁的使用)