系统整容纪:用知识来“武装“自己~认识MySQL的锁与事务

💡 原文中文,约19700字,阅读约需47分钟。
📝

内容提要

本文介绍了MySQL锁和事务的基本知识,并解决了一个关于事务中select语句的问题。通过实际操作验证,InnoDB引擎和可重复读隔离级别下的普通select语句不带锁。问题最终发现在spring事务超时设置上,成功解决了问题。

🔎

延伸解读

普通SELECT在可重复读下为何不加锁

文章通过实际验证指出,在InnoDB的可重复读隔离级别下,普通SELECT语句采用一致性读,读取的是事务开始时的快照,不会加锁。这意味着并发事务的写操作不会阻塞这类查询,但查询也看不到其他事务已提交的最新数据。理解这一点有助于避免误判锁冲突,也能解释为何某些查询在长事务中仍能快速返回。

Spring事务超时设置如何引发异常

案例中,业务方法声明了60秒的事务超时,而整个大事务执行超过了该时限,导致后续SQL报出事务超时异常。尽管报错SQL本身仅执行1毫秒,但事务超时是全局性的,一旦触发,事务内所有操作都可能失败。这提醒开发者,在长事务中需合理评估超时时间,并关注事务边界,避免因超时导致业务中断。

锁机制与索引的紧密关联

文章强调,InnoDB的行锁是基于索引实现的。命中唯一索引时,若记录存在则加行锁,不存在则加间隙锁;命中普通索引时,会同时加行锁和间隙锁;若未命中索引,则锁升级为表锁。因此,SQL是否走索引直接影响锁的粒度和并发性能。在设计数据库和编写查询时,应确保条件能有效利用索引,以减少锁冲突。

排查问题时的思路与收获

作者最初怀疑事务中的SELECT持有共享锁,但经学习和验证推翻了这一假设,最终定位到Spring事务超时。这个过程展示了排查复杂问题时,需结合数据库原理与应用框架机制,逐步验证假设。即使推测错误,也能加深对知识的理解,为后续开发与调优积累经验。

❓

Q&A

MySQL中的锁有哪些类型?

MySQL中的锁主要有共享锁、排他锁、行锁、间隙锁、临键锁、表锁和意向锁等。

什么是MySQL的事务?

MySQL的事务是一组操作序列,这些操作要么全部执行,要么全部不执行,具有原子性、一致性、隔离性和持久性(ACID特性)。

MySQL的可重复读隔离级别如何防止幻读?

可重复读隔离级别通过使用间隙锁和临键锁来防止幻读,确保在事务执行期间不会插入新的记录。

如何解决MySQL中的死锁问题?

可以通过顺序访问资源、设置合理的超时时间、使用行锁而非表锁、尽早释放锁和减少事务大小等策略来解决死锁问题。

MySQL的多版本并发控制(MVCC)是什么?

MVCC是一种允许在不加锁的情况下进行读取的技术,通过为每个事务创建快照,提高了系统的并发性能。

在MySQL中,普通的select语句是否会加锁?

在InnoDB引擎和可重复读隔离级别下,普通的select语句不会加锁,而是执行一致性读,读取记录的快照。

🏷️

标签

➡️

继续阅读