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 整张表就是。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容