美文网首页程序员MySQL 开发MySQL
MySQL 并发控制 -- 读锁、写锁、乐观锁

MySQL 并发控制 -- 读锁、写锁、乐观锁

作者: 殷天文 | 来源:发表于2019-03-25 22:24 被阅读12次

并发是一个让人很头疼的问题,通常我们会在服务端或者数据库端做处理,保证在并发下数据的准确性,今天我们简要的讨论一下MySQL中如何通过锁解决并发问题

读锁

  • 也叫共享锁 (shared lock)

  • 如何使用
    SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE

  • 详解
    即事务A 使用共享锁 获取了某条(或者某些)记录时,事务B 可以读取这些记录,可以继续添加共享锁,但是不能修改或删除这些记录(当事务B 对这些数据修改或删除时会进入阻塞状态,直至锁等待超时或者事务A提交)

  • 使用场景
    读取结果集的最新版本,同时防止其他事务产生更新该结果集
    主要用在需要数据依存关系时确认某行记录是否存在,并确保没有人对这个记录进行UPDATE或者DELETE操作

  • 注意事项
    当使用读锁时,避免产生如下操作

事务1
BEGIN;
select * from sys_user where id = 1 LOCK IN SHARE MODE; (步骤1)

update sys_user set username = "taven" where id = 1; (步骤3,发生阻塞)
COMMIT;
事务2
BEGIN;
select * from sys_user where id = 1 LOCK IN SHARE MODE; (步骤2)

update sys_user set username = "taven" where id = 1; (步骤4,死锁)
COMMIT;
  • 分析
    根据我们之前对读锁定义可知,当有事务拿到一个结果集的读锁时,其他事务想要更新该结果集,需要拿到读锁的事务提交(释放锁)。而上述情况两个事务分别拿到了读锁,而且都有update 操作,两个事务互相等待造成死锁(都在等待对方释放读锁)

写锁

  • 也叫排它锁(exclusive lock)

  • 如何使用
    SELECT * FROM table_name WHERE ... FOR UPDATE

  • 详解
    一个写锁会阻塞其他的读锁和写锁
    即事务A 对某些记录添加写锁时,事务B 无法向这些记录添加写锁或者读锁(不添加锁的读取是可以的),事务B 也无法执行对 锁住的数据 update delete

  • 使用场景
    读取结果集的最新版本,同时防止其他事务产生读取或者更新该结果集
    例如:并发下对商品库存的操作

  • 注意事项
    在使用读锁、写锁时都需要注意,读锁、写锁属于行级锁。即事务1 对商品A 获取写锁,和事务2 对商品B 获取写锁互相不会阻塞的。需要我们注意的是我们的SQL要合理使用索引,当我们的SQL 全表扫描的时候,行级锁会变成表锁
    使用EXPLAIN查看 SQL是否使用了索引,扫描了多少行

乐观锁

  • 上述介绍的是行级锁,可以最大程度地支持并发处理(同时也带来了最大的锁开销)乐观锁是一种逻辑锁,通过数据的版本号(vesion)的机制来实现,极大降低了数据库的性能开销。

  • 我们为表添加一个字段 version,读取数据时将此版本号一同读出,之后更新时,对此版本号+1,同时将提交数据的version 与数据库中对应记录的当前version 进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据

update t_goods 
set status=2,version=version+1
where id=#{id} and version < #{version}; // 更新前将version自增

或者

update t_goods 
set status=2,version=version+1
where id=#{id} and version = #{version}; // 更新前version 不自增

相关文章

  • MySQL 并发控制 -- 读锁、写锁、乐观锁

    并发是一个让人很头疼的问题,通常我们会在服务端或者数据库端做处理,保证在并发下数据的准确性,今天我们简要的讨论一下...

  • 表锁和行锁

    MySQL中的锁总体可以分为悲观锁和乐观锁。悲观锁MySQL中有自带的锁。乐观锁需要自己写程序控制来实现乐观锁的功...

  • Mysql相关

    Mysql相关 Mysql并发控制-锁 共享锁 共享锁也称为读锁,读锁允许多个连接可以同一时刻并发的读取同一资源,...

  • MySQL中的锁和并发控制

    综述 对MySQL中并发控制所用到的机制和锁进行整理。 行锁 表锁 间隙锁 临键锁 MVCC 悲观锁 乐观锁 行锁...

  • MySQL架构与历史

    1.MySQL逻辑架构 2.并发控制 ①读写锁 共享锁:也叫读锁,相互不阻塞。排他锁:也叫写锁,一个写锁会阻塞其他...

  • mysql锁

    mysql锁 性能:乐观锁,悲观锁 操作类型:读锁,写锁,都属于悲观锁 操作粒度:行锁,表锁 乐观锁:一种思想,通...

  • mysql锁记录

    mysql锁 性能:乐观锁,悲观锁 操作类型:读锁,写锁,都属于悲观锁 操作粒度:行锁,表锁 乐观锁:一种思想,通...

  • java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁

    基础 锁的类型 锁从宏观上分类,分为悲观锁与乐观锁 乐观锁 乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能...

  • Spring Elasticsearch data 乐观锁并发控

    Spring ElasticSearch data 乐观锁并发控制 乐观锁与悲观锁 悲观锁(Pessimistic...

  • ElasticSearch 7.x 实战入门06

    本节的主要内容:ES的乐观锁并发控制原理以及模拟过程 1、ES的乐观锁并发控制 1.1、悲观锁与乐观锁 悲观锁的优...

网友评论

    本文标题:MySQL 并发控制 -- 读锁、写锁、乐观锁

    本文链接:https://www.haomeiwen.com/subject/gjkivqtx.html