深入理解mysql事务隔离与锁机制
2026-01-06 10:21:56 0 举报
AI智能生成
本文档深入解析了MySQL中的事务隔离和锁机制,探讨了MySQL为保证数据一致性、有效隔离并发事务而采取的核心机制。介绍了包括读未提交(RU)、读已提交(RC)、可重复读(RR)、串行化(S)在内的四种隔离级别,并详述了每种隔离级别下的潜在问题及其应用场景。同时,深入剖析了MySQL所采用的锁机制,包括乐观锁、悲观锁、行锁、表锁等,讲解了这些锁的使用场景和性能影响,以及其在高并发环境下的表现。
作者其他创作
大纲/内容
事务
什么是事务?
数据库操作中一组sql语句组成的逻辑处理单元,它由一个或者多个sql语句组成。操作要么全部成功,要么全部失败。
事务特性:ACID
A(原子性)
核心:事务的所有操作要么全部成功,要么全部失败回滚。
实现:通过mysql的undo log(回滚日志)实现,如果事务失败,mysql通过undo log 将数据恢复到事务开始前的状态。
实现:通过mysql的undo log(回滚日志)实现,如果事务失败,mysql通过undo log 将数据恢复到事务开始前的状态。
C(一致性)
核心:事务执行前后,数据库必须从一个一致性状态变换到另一个一致性状态。
原子性,隔离性,持久性都是为了保证事务的最终一致性而存在的
原子性,隔离性,持久性都是为了保证事务的最终一致性而存在的
I(隔离性)
核心:一个事务所做的修改在最终提交之前,对其他事务是不可见的,多个并发事务之间要相互隔离,防止数据不一致。
问题:如果没有隔离性,会引发脏读,不可重复读,幻读等问题。
实现:mysql通过mvcc和锁机制来实现,mysql不同的事物隔离级别(读未提交,读已提交,可重复读,串行化)来平衡隔离性和并发性能。
问题:如果没有隔离性,会引发脏读,不可重复读,幻读等问题。
实现:mysql通过mvcc和锁机制来实现,mysql不同的事物隔离级别(读未提交,读已提交,可重复读,串行化)来平衡隔离性和并发性能。
D(持久性)
核心:一旦事物提交后,其所做的修改就是永久保存到数据库中,即使系统发生崩溃,数据也不会丢失。
实现:通过redo log实现,修改数据时,mysql会先写redo log,
实现:通过redo log实现,修改数据时,mysql会先写redo log,
查看当前数据库事务命令
mysql5.7:show variables like 'tx_isolation'
msyql8.0:show variables like '%isolation%'
设置当前链接事务级别命令
mysql5.7:set tx_isolation='repeatable-read'
mysql8.0:set transaction_isolation='repeatable-read'
并发事务处理带来的问题
丢失更新或脏写
最后的更新覆盖之前事务所做的更新
脏读
事务A 读取到了事务B已经修改但尚未提交的数据
不可重复读
事务A 中相同的查询每次结果都不相同,不符合隔离性要求
幻读
事务A读取到了B事务新增的数据。
事务隔离级别
读未提交(read uncommitted)
读已提交(read committed)
可重复读(repeatable read)
mysql默认事务隔离级别
串行化(serializable)
锁
什么是锁?
锁是计算机协调多个进程或线程并发访问某一共同资源的机制
锁分类
性能上区分
乐观锁
用版本对比来实现
建议用于读多写少的场景,写多话版本变化太快,等待太长,开销大
悲观锁
建议用于读少写多的场景
数据库操作类型
读锁(共享锁 S)
针对同一份数据,多个读操作可以同时进行而不会相互影响
写锁(排它锁)
当写操作没有完成前,会阻塞其他写锁与读锁
表锁
特点:每次操作锁住整张表,开销小,加锁快,不会出现死锁,锁粒度大,发生锁冲突的概率最高,并发度最低。一般用在整张表数据迁移的场景。
手动增加表锁命令
lock table 表名称 read(write),表名称2 read(write)
查看表锁命令
show open tables
删除表锁命令
unlock tables
行锁
特点:每次操作锁定一行数据,开销大,加锁慢,会出现死锁,锁粒度小,并发度高。
innodb的行锁是作用在索引项上的,不是针对记录行加锁,索引失效在RR隔离级别下会表现为表锁效果。
RR级别下:如果查询字段没有索引,全表扫描,为了防止幻读,由于间隙锁与临键锁的原因,会锁住全部行,效果相当于表锁
RC级别下:由于没有间隙锁,只锁定实际符合条件的行,不会影响插入操作。
间隙锁
锁的就是两个值之间的空隙,在可重复读隔离级别下生效,能一定程度帮组可重复读解决幻读问题。
临键锁
行锁与间隙锁的组合。
MDL锁
防止事务过程中DDL操作带来的数据不一致
意向锁(表级锁)
IS(意向共享锁)
给数据行加读锁前先取得该表的IS锁,防止事务过程中DDL操作带来的数据不一致
IX(意向排它锁)
给数据行加写锁前先取得该表的IX锁,防止事务过程中DDL操作带来的数据不一致
锁优化
通过查看innodb_row_lock来分析行锁争夺情况
show status like 'innodb_row_lock%'
innodb_row_lock_current_waits:当前正在等待锁定的数量
innodb_row_lock_time:从系统启动到现在锁定总时间长度
innodb_row_lock_time_avg:每次等待所花平均时间
innodb_row_lock_time_max:从系统启动到现在锁等待最长的一次花费时长
innodb_row_lock_waits:等待总次数
锁优化建议
尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁。
合理设计索引,尽量缩小锁范围。
尽可能减少检索条件范围,避免间隙锁
尽可能低级别事务隔离
尽量控制事务大小,减少锁定资源量和时间长度,涉及事务加锁的sql尽量做后执行。
0 条评论
下一页