首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

mysql 写锁会等待读锁

基础概念

MySQL中的锁机制用于控制多个事务对数据的并发访问。写锁(Write Lock)和读锁(Read Lock)是两种常见的锁类型:

  • 读锁(Read Lock):允许多个事务同时读取同一数据,但不允许其他事务对该数据进行写操作。
  • 写锁(Write Lock):只允许一个事务对数据进行写操作,其他事务无法读取或写入该数据。

相关优势

  • 读锁的优势:允许多个事务并发读取数据,提高了读操作的并发性能。
  • 写锁的优势:确保数据在写操作期间不会被其他事务修改,保证了数据的一致性和完整性。

类型

  • 共享锁(Shared Lock):即读锁,允许多个事务同时读取同一数据。
  • 排他锁(Exclusive Lock):即写锁,只允许一个事务对数据进行写操作。

应用场景

  • 读锁的应用场景:适用于读多写少的场景,如报表生成、数据查询等。
  • 写锁的应用场景:适用于数据更新、插入、删除等写操作频繁的场景。

问题描述

当一个事务持有读锁时,另一个事务尝试获取写锁,写锁会等待读锁释放。这是因为写锁需要独占数据,而读锁允许多个事务并发读取数据。

原因

MySQL的锁机制遵循以下规则:

  1. 读锁之间不互斥:多个事务可以同时持有读锁。
  2. 写锁与读锁互斥:写锁需要独占数据,因此当一个事务持有读锁时,其他事务无法获取写锁。
  3. 写锁之间互斥:只有一个事务可以持有写锁。

解决方法

  1. 优化事务隔离级别:根据业务需求选择合适的事务隔离级别,如READ COMMITTEDREPEATABLE READ,以减少锁冲突。
  2. 减少事务持有锁的时间:尽量缩短事务的执行时间,减少锁的持有时间。
  3. 使用乐观锁:通过版本号或时间戳等方式实现乐观锁,减少锁的使用。
  4. 分表分库:通过分表分库减少单个表的并发压力。

示例代码

以下是一个简单的示例,展示如何在MySQL中使用读锁和写锁:

代码语言:txt
复制
-- 开启事务并获取读锁
START TRANSACTION;
SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;
-- 执行读操作
COMMIT;

-- 开启事务并获取写锁
START TRANSACTION;
SELECT * FROM table_name WHERE id = 1 FOR UPDATE;
-- 执行写操作
UPDATE table_name SET column = 'new_value' WHERE id = 1;
COMMIT;

参考链接

通过以上方法,可以有效管理和优化MySQL中的锁机制,提高系统的并发性能和数据一致性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

MySQL锁相关总结|悲观锁、乐观锁、读锁、写锁、表锁、行锁、页面锁、间隙锁、临键锁

MySQL锁总体结构 MySQL 的锁可以分成三类:总体、类型、粒度。...乐观锁 乐观锁对于数据库的数据的读写持乐观态度,即在整个数据处理的过程中,他会很乐观的认为数据会保持一致性,所以不加锁,而是通过数据版本记录机制实现。...写锁 写锁又称为排他锁或者X锁(Exclusive Lock),如果当前写锁未释放,他会阻塞其他的写锁和读锁。 5. 表锁 表锁也称为表级锁,就是在整个数据表上对数据进行加锁和释放锁。...在MySQL中,有两种表锁模式:一种是表共享锁(Table Shard Lock),另一种是表独占写锁(Table Write Lock)。...那么对应的如果一个线程获取到一个表的写锁后,只有这个线程可以进行读写操作,其他线程无法对表进行读写操作,直到写锁被释放为止。

27210

读锁写锁

ReentrantReadWriteLock其读锁是共享锁,共写锁是独占锁。 读锁的共享锁可以保证并发读是非常高效的,读写,写读,写写的过程是互斥的。...注: 但是会出现写一个问题,就是写饥饿现象,上方我们是先运行了所有的写线程,读线程是在写线程后执行的,假如读线程的数量大于写线程数量的话,因锁的大概率都被读线程执行了,就会造成一种写饥饿现象,写线程无法满足大量读线程的读操作...,因为写线程少的时候会抢不到锁。...通过乐观锁,当写线程没有写数据的时候,标志位stamp并没有改变,所以即使有再多的读线程读数据,他都可以读取,而无需获取锁,这就不会使得写线程抢不到锁了。...可以看到结果,读锁都可以同时获取锁,就算写线程没有写入数据所有读线程还是在抢占锁,使用ReadWriteLock也是会出现同样的现象,写饥饿。

1K31
  • 独占锁(写锁)共享锁(读锁)互斥锁

    独占锁:指该锁一次只能被一个线程所持有。对ReentrantLock和Synchronized而言都是独占锁 共享锁:指该锁可被多个线程所持有。...对ReentrantReadWriteLock其读锁是共享锁,其写锁是独占锁。 读锁的共享锁可保证并发读是非常高效的,读写,写读,写写的过程是互斥的。...使用方法 声明一个读写锁 如果需要独占锁则加从可重入读写锁里得到写锁 写锁demo 如果需要共享锁则加从可重入读写锁里得到读锁 读锁demo ReentrantReadWriteLock实现原理简单分析...Sync是如何同时表示读锁与写锁?...,低16位表示写锁个数 一个线程获取到了写锁,并且重入了两次,低16位是3,线程又获取了读锁,并且重入了一次,高16位就是2 读锁的写锁的获取主要调用AQS的相关Acquire方法,其释放主要用了相关Release

    1.4K30

    小白学习MySQL - 查询会锁表?

    我们知道,Oracle中除了使用select ... for update,其他查询语句不会出现锁,即没有读锁,读一致性通过多版本解决的,可以保证在不加锁的情况下读到正确的数据。...问题来了,Oracle中执行的insert into select很正常,不会出现锁表,难道相同的语句用在了MySQL,就会锁住整张表?...test_1加任何的锁,只是对'test_1'这行记录加了共享锁(lock mode S locks gap before rec),其实是加到了索引上, mysql> show engine innodb...test_2上是没有任何锁,因此不会出现RR会锁定test_2的情况, mysql> show engine innodb status \G; ... ------------ TRANSACTIONS...而在RR模式,虽然两个事务做到了真正的隔离,但实际通过加锁,还是会产生一些问题的,因此隔离级别的选择,其实还是一种权衡的。

    2.4K30

    MySQL乐观锁(MySQL乐观锁)

    悲观锁与乐观锁的区别 悲观锁会把整个对象加锁占为已有后才去做操作,Java中的Synchronized属于悲观锁。...悲观锁有一个明显的缺点就是:它不管数据存不存在竞争都加锁,随着并发量增加,且如果锁的时间比较长,其性能开销将会变得很大。...乐观锁不获取锁直接做操作,然后通过一定检测手段决定是否更新数据,这种方式下,已经没有所谓的锁概念了,每条线程都直接先去执行操作,计算完成后检测是否与其他线程存在共享数据竞争,如果没有则让此操作成功,如果存在共享数据竞争则可能不断地重新执行操作和检测...乐观锁的缺点 现在已经了解乐观锁及CAS相关机制,乐观锁避免了悲观锁独占对象的现象,同时也提高了并发性能,但它也有缺点: 观锁只能保证一个共享变量的原子操作。...乐观锁是对悲观锁的改进,虽然它也有缺点,但它确实已经成为提高并发性能的主要手段,而且jdk中的并发包也大量使用基于CAS的乐观锁。

    1.5K10

    【MySQL】MySQL锁(二)表锁与行锁测试

    但是,接着我们又让 客户端2 加一个 写锁 ,这个时候就无法正常加了。也就是说,S 与 X 是互斥的,有一个拿到读锁之后,写锁就没办法再加上了,只能等 客户端1 的锁释放之后才能进行操作。...要注意,我们现在是锁的整表哦。 接下来,我们就来试试为整张表锁上 写锁 。...但是 UNLOCK 不能针对某一张表,而是使用 UNLOCK TABLES; MySQL 会自动进行解锁释放。 全局锁 除了单独锁一张表之外,我们还可以锁一个库中所有的表。...对于上面的 意向共享 S 锁 来说,我们可以继续加表锁,不过只能加 读锁 ,无法加 写锁 。...,同时锁也会变成 表锁 ,因此,下面针对某条单行数据的更新语句就会阻塞。

    23110

    【MySQL】MySQL锁(三)元数据锁与间隙锁

    MySQL锁(三)元数据锁与间隙锁 在上篇文章中,我们就提到过 元数据锁 和 间隙锁 这两个名词,不知道有没有吊起大家的胃口。这俩货又是干嘛的呢?别急,我们一个一个来看。...其实在默认情况下,行锁 就是 临键锁 ,它会锁自己以及附近的数据,但是,如果是主键或者唯一索引,会退化成 记录锁 ,也就是我们习惯说的那个 “行锁” ,而在大部分情况下,普通的间隙空值操作也会退化为 间隙锁...其实在这里,事务2 虽然也产生了阻塞,但是当 事务1 提交之后,事务2 会马上拿到锁,事务3 还是会在阻塞状态,紧接着 事务2 提交后,事务3 就会插入失败。...因此,后面我们插入一条 id 为 45 的数据也会阻塞。 因此,在 更新/删除 数据时,如果是范围条件,即使有索引,也会锁很多间隙,特别是 id 或数据不连续(普通索引)的情况下。...插入数据的情况稍微好一点,毕竟我们会更习惯于自增主键的形式插入,但也要注意 自增锁 的情况,这个锁我们下回再说。 总结 是不是感觉 间隙锁 非常复杂?

    21210

    MySQL中的锁(表锁、行锁)

    MySQL表级锁的锁模式     MySQL的表锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。...如何加表锁     MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预...MyISAM的锁调度 前面讲过,MyISAM存储引擎的读和写锁是互斥,读操作是串行的。那么,一个进程请求某个MyISAM表的读锁,同时另一个进程也请求同一表的写锁,MySQL如何处理呢?...答案是写进程先获得锁。不仅如此,即使读进程先请求先到锁等待队列,写请求后到,写锁也会插到读请求之前!这是因为MySQL认为写请求一般比读请求重要。...、数据行等,并分析锁争用的原因。

    4.9K10

    【MySQL】MySQL锁(四)其它锁概念

    MySQL锁(四)其它锁概念 好了,锁相关内容的最后一篇文章了。其实最核心的内容,表锁、行锁、读锁、写锁、间隙锁这些重要的内容我们都已经学习过了,特别是间隙锁,是不是感觉非常复杂。...它是一个 表级锁 ,因为要保证多个线程同时插入数据时的增长序列,所以会以锁的方式实现。 什么意思呢?...,第一个事务是一个读锁,第二个事务是一个写锁。...悲观锁 悲观锁对数据被其他事务的修改持保守态度,每次拿数据都觉得别人会修改数据,所以别人拿到锁之前都会先上锁,MySQL 中的锁机制就是悲观锁。...如果事务都执行得很快,一般也会不有太大问题。而且我们大部分的业务都是 读多写少 的场景,毕竟 S 锁是共享的,所以大家日常只是需要注意一下大批量的更新和删除操作以及无法容忍的慢查询语句即可。

    14310

    MySQL中的锁(表锁、行锁,共享锁,排它锁,间隙锁)

    本章我们着重讨论MySQL锁机制 的特点,常见的锁问题,以及解决MySQL锁问题的一些方法或建议。 Mysql用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。...如何加表锁 MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作 (UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,...MyISAM的锁调度 前面讲过,MyISAM存储引擎的读锁和写锁是互斥的,读写操作是串行的。那么,一个进程请求某个 MyISAM表的读锁,同时另一个进程也请求同一表的写锁,MySQL如何处理呢?...答案是写进程先获得锁。不仅如此,即使读请求先到锁等待队列,写请求后 到,写锁也会插到读锁请求之前!这是因为MySQL认为写请求一般比读请求要重要。...数据行等,并分析锁争用的原因。

    2.5K30

    MySQL:表级锁、行级锁、共享锁、排他锁、乐观锁、悲观锁

    锁粒度大,发生锁冲突概率大,并发效率低。 适合查询。 行级锁: row-level loking,锁住一行记录。 开销大,加锁慢。 会死锁。 锁粒度小,发生所冲突概率小,并发效率高。...适合并发写,事务控制。 并不是直接丢记录行加锁,而是对行对应的索引加锁: 如果sql 语句操作了主键索引,Mysql 就会锁定这条主键索引。...如果sql语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。 在InnoDB中,如果SQL语句不涉及索引,则会通过隐藏的聚簇索引来对记录加锁。...语法:select id from t_table in share mode; 多个共享锁可以共存,共享锁与排他锁不能共存。 排他锁: 又称之为X锁、写锁。...悲观锁: 悲观锁:悲观地认为,并发问题极易发生。 悲观锁认为并发问题极易发生,所以每次操作,无论读写,都会对记录加锁,以防止其他线程对数据进行修改。 实现方式:数据库的行锁、读锁和写锁。

    1.1K20

    ⑩⑦【MySQL】锁:全局锁、表级锁、行级锁

    设置全局锁: FLUSH TABLES WITH READ LOCK; MySQL数据备份: # MySQL数据库备份的 (命令行指令) mysqldump -uroot -p密码 备份数据库名>保存备份的文件名...表级锁 表级锁: 表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低 。应用在MyISAM、InnoDB、BDB等存储引擎中。...写锁即阻塞其他客户端的读操作又阻塞其他客户端的写操作 元数据锁 ②元数据锁(meta data lock,MDL) : ⚪MDL加锁过程是系统自动控制 ,无需显式使用,在访问一张表的时候会自动加上。...⚪在MySQL5.5中引入了MDL,当对一张表进行增删改查的时候,加MDL读锁(共享) ;当对表结构进行变更操作的时候,加MDL写锁(排他) 。...索引上的范围查询(唯一索引),会访问到不满足条件的第一个值为止。 间隙锁唯一目的是防止其他事务插入间隙 。间隙锁可以共存 ,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁。

    43330

    MySQL表锁、行锁、排它锁和共享锁

    专栏持续更新中:MySQL详解 事务隔离级别的实现原理:简单来说就是各种锁机制和MVCC多版本并发控制 我们学习知识的时候,需要了解知识点出现的原因,什么情况下能用到这个知识 我们说到事务,就得说到事务的...一、事务隔离机制的选择 如果我们完全不管,使用未提交读的事务隔离机制,任由这些线程并发操作数据库,那就会出现脏读(读取了未commit的数据)、不可重复读(两次查询值不同)、幻读(两次查询数据量不同)等问题...此时会放弃使用索引,因此也不会使用行锁,而是使用表锁,比如对一些很小的表,MySQL就不会去使用索引 三、排它锁(Exclusive)和共享锁(Shared) 排它锁,又称为X锁,写锁 共享锁,又称为...因为现在name走的是索引, 通过zhangsan在辅助索引树上找到它所在行记录的id是7,然后到主键索引树上,获取对应行记录的排他锁(MySQL Server会根据情况,在主键索引树和辅助索引树上加锁...Server会根据情况,在主键索引树和辅助索引树上加锁) 我们update id=8的数据,成功了。

    29540

    技术分享 | MySQL中查询会锁表 ?

    bisal ,具有十年以上的应用运维工作经验,目前主要从事数据库应用研发能力提升方面的工作,Oracle ACE ,拥有 Oracle OCM & OCP 、EXIN DevOps Master 、SCJP 等国际认证...问题来了,Oracle 中执行的 insert into select 很正常,不会出现锁表,难道相同的语句用在了 MySQL ,就会锁住整张表?...1'这行记录加了共享锁(lock mode S locks gap before rec),其实是加到了索引上, mysql> show engine innodb status \G; ... --...test_2 上是没有任何锁,因此不会出现 RR 会锁定 test_2 的情况, mysql> show engine innodb status \G; ... ------------ TRANSACTIONS...而在 RR 模式,虽然两个事务做到了真正的隔离,但实际通过加锁,还是会产生一些问题的,因此隔离级别的选择,其实还是一种权衡的。 ----

    5.5K10

    MySQL排它锁之行锁、间隙锁、后码锁

    MySQL InnoDB支持三种行锁定 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key。 间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙不变。...行锁(Record Lock) 当需要对表中的某条数据进行写操作(insert、update、delete、select for update)时,需要先获取记录的排他锁(X锁),这个就称为行锁。...Gap Lock) 在MySQL中select称为快照读,不需要锁,而insert、update、delete、select for update则称为当前读,需要给数据加锁,幻读中的“读”即是针对当前读...*/ COMMIT; 我们可以看出,指定查询某一条记录时,如果这条记录不存在,会产生间隙锁 结论 对于指定查询某一条记录的加锁语句,如果该记录不存在,会产生记录锁和间隙锁,如果记录存在,则只会产生记录锁...,只会加记录锁,不会产生间隙锁; 普通索引不管是锁住单条,还是多条记录,都会产生间隙锁; 间隙锁会封锁该条记录相邻两个键之间的空白区域,防止其它事务在这个区域内插入、修改、删除数据,这是为了防止出现 幻读

    2.8K11

    MySQL中的锁(表锁、行锁)

    MySQL表级锁的锁模式 MySQL的表锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。...如何加表锁 MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此用户一般不需要直接用...MyISAM的锁调度 前面讲过,MyISAM存储引擎的读和写锁是互斥,读操作是串行的。那么,一个进程请求某个MyISAM表的读锁,同时另一个进程也请求同一表的写锁,MySQL如何处理呢?...答案是写进程先获得锁。不仅如此,即使读进程先请求先到锁等待队列,写请求后到,写锁也会插到读请求之前!这是因为MySQL认为写请求一般比读请求重要。...、数据行等,并分析锁争用的原因。

    5.1K20

    Mysql锁详解(行锁、表锁、意向锁、Gap锁、插入意向锁)

    (1)首先明确并存的概念是指数据库同时支持表、行锁,而不是任何情况都支持一个表中同时有一个事务A持有行锁、又有一个事务B持有表锁,因为表一旦被上了一个表级的写锁,肯定不能再上一个行级的锁。...因为上了表级S锁后,不允许其他事务再加X锁,所以表级S锁和X、IX锁不兼容 上了表级X锁后,会修改数据,所以表级X锁和 IS、IX、S、X(即使是行排他锁,因为表级锁定的行肯定包括行级速订的行,所以表级...注意:上了行级X锁后,行级X锁不会因为有别的事务上了IX而堵塞,一个mysql是允许多个行级X锁同时存在的,只要他们不是针对相同的数据行。...(4)插入意向锁不会阻止任何锁,对于插入的记录会持有一个记录锁。...test where n > 4 for update,事务B会申请Gap锁(4, ∞),申请成功后,被事务A的x锁阻塞,直到x锁被释放。

    2.3K30

    MySQL 锁

    锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中。...释放锁:unlock tables / 客户端断开连接 。 特点: A. 读锁 左侧为客户端一,对指定表加了读锁,不会影响右侧客户端二的读,但是会阻塞右侧客户端的写。...测试: B.写锁 左侧为客户端一,对指定表加了写锁,会阻塞右侧客户端的读和写。 测试: 结论 读锁不会阻塞其他客户端的读,但是会阻塞写。写锁既会阻塞其他客户端的读,又会阻塞其他客户端的写。...在MySQL5.5中引入了MDL,当对一张表进行增删改查的时候,加MDL读锁(共享);当对表结构进行变更操作的时候,加MDL写锁(排他)。...EXCLUSIVE 与其他的MDL都互斥 演示: 当执行SELECT、INSERT、UPDATE、DELETE等语句时,添加的是元数据共享锁(SHARED_READ / SHARED_WRITE),之间是兼容的

    1.3K10

    扫码

    添加站长 进交流群

    领取专属 10元无门槛券

    手把手带您无忧上云

    扫码加入开发者社群

    相关资讯

    热门标签

    活动推荐

      运营活动

      活动名称
      广告关闭
      领券